пример использования
boost::function<bool()> f = functor<bool(), predicate, false);
Няшно #include <iostream> struct end { ~end() { std::cout << std::endl; } }; #define log end(), std::cout int main() { log << "Hello! " << 2; log << "Hello! " << 3; return 0; }
Шаблонные шаблонные параметры это прошлый век, они не удобны. Есть способы их избегать. Например: есть класс A, в котором нужно объявлять контейнер из произвольного типа, а тип контейнера передавать параметром шаблона: template <typename T, typename Container> struct A { typedef Container<T> type; }; Но так как Container это шаблон, принимающий два параметра: тип данных и тип аллокатора, то следует писать так: template <typename T, template<typename, typename> class Container> struct A { typedef Container<T, std::allocator<T> > type; } Но я не охочу указывать явно и самостоятельно тип аллокатора, это может првести к ошибке. Чтобы получить тип теперь мы должны вызвать: typedef A<int, std::vector>::type type; В boost mpl есть плейсхолдеры, которые используются для создания лямбда метафункций. С помощью них можно избежать создания шаблонных шаблонных параметров. То есть я передаю в шаблон A уже инстанцированный шаблон так: typedef A<int, std::vector<boost::mpl::_1> >::type type; Тогда в шаблоне A инстанцирование конейнера с произвольным типом будет выглядеть так: #include <boost/mpl/apply.hpp> template <typename T, typename Container> struct A { typedef boost::mpl::lambda<Container> lambda; typedef typename boost::mpl::apply<lambda, T>::type type; };
Только сейчас обнаружил для себя BOOST_AUTO (#include <boost/typeof/std/utility.hpp>), например, перебирать итераторы можно вместо громоздкого for (std::map<int, int>::const_iterator iter = a.begin(); iter != a.end(); ++iter) так: for (BOOST_AUTO(iter, a.begin()); iter != a.end(); ++iter)
Вычисление квадратного корня в рациональных числах на этапе компиляции. Пример: Создаём рациональное число 20: typedef rational<20,1> a; // 20 - делимое, 1 - делитель std::cout << sqrt<a>::type::get() << std::endl; Для работы с рациональными числами нужно создать дополнительную структуру и описать математические операции для неё. Для корня используется алгоритм Ньютона (см. struct sqrt_eval) #include <stdint.h> template <int64_t A, int64_t B> struct rational { const static int64_t a = A, b = B; static double get() { return (double)a/b; }; }; template <class R> struct reduce { const static int64_t max = 1<<30; const static bool do_reduce = (R::a > max) || (R::b > max); typedef rational<do_reduce?(R::a >> 15):R::a, do_reduce?(R::b >> 15):R::b> type; }; template <class R1, class R2> struct plus { typedef rational<R1::a * R2::b + R2::a * R1::b, R1::b * R2::b> type1; typedef typename reduce<type1>::type type; }; template <class R1, class R2> struct minus { typedef rational<R1::a * R2::b - R2::a * R1::b, R1::b * R2::b> type1; typedef typename reduce<type1>::type type; }; template <class R1, class R2> struct mult { typedef rational<R1::a * R2::a, R1::b * R2::b> type1; typedef typename reduce<type1>::type type; }; template <class R1, class R2> struct divide { typedef rational<R1::a * R2::b, R1::b * R2::a> type1; typedef typename reduce<type1>::type type; }; template <class R1, class R2> struct rational_less { static const bool value = (R1::a * R2::b - R2::a * R1::b) < 0; }; template <bool, class A1, class A2> struct meta_if { typedef A2 type; }; template <class A1, class A2> struct meta_if<true, A1, A2> { typedef A1 type; }; template <int64_t p, class res, class x> struct sqrt_eval { typedef typename divide<x, res>::type t1; typedef typename plus<res, t1>::type t2; typedef typename divide<t2, rational<2,1> >::type tmp; typedef typename meta_if<rational_less<tmp, res>::value, tmp, res>::type less_val; typedef typename sqrt_eval<p-1, less_val, x>::type type; }; template <class res, class x> struct sqrt_eval<0, res, x> { typedef res type; }; template <class x> struct sqrt { typedef typename divide< typename plus<x, rational<1,1> >::type, rational<2,1> >::type res; typedef typename sqrt_eval<15, res, x>::type type; }; template <int64_t a> struct sqrt< rational<0, a> > { static const int64_t value = 0; };
Вычисление квадратного корня в целых числах на этапе компиляции пример assert(sqrt<81>::value == 9); template <bool> struct while_f { template <int res, int x> struct calc_res { const static int tmp = (res+x/res)/2; typedef typename while_f<(res > tmp)>::template calc_res<(tmp<res)?tmp:res, x> a; static const int value = a::value; }; }; template <> struct while_f<false> { template <int res, int x> struct calc_res { static const int value = res; }; }; template <int x> struct sqrt { static const int value = while_f<true>::calc_res<(x+1)/2, x>::value; }; template <> struct sqrt<0> { static const int value = 0; };
скомпилируется ли код и что выдаст программа? #include <iostream> using namespace std; struct A { A() { cout << __func__ << endl; } ~A() { cout << __func__ << endl; } }; int main() { A::A::A::A(); return 0; }
скомпилируется ли следующий пример? struct A { }; struct B { B(int&) {} }; int main() { A(); int k; B(k); return 0; }