← All posts tagged C++

sany
C++ boost ? Что-то не могу осилить. Нужно создать функтор, который выполняется при условии, иначе возвращает дефолтное значение. Есть что-то подобное в бусте, например?

пример использования
boost::function<bool()> f = functor<bool(), predicate, false);
sany
C++ boost ? Можно ли как-то создать создать специализацию шаблона для типов, для которых определена операция std::ostream::opertor<< ?
sany
code C++ mpl boost
Шаблонные шаблонные параметры это прошлый век, они не удобны.
Есть способы их избегать. Например:
есть класс 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;
};
sany
code C++ slow boost
Только сейчас обнаружил для себя 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)
sany
code C++ math templates
Вычисление квадратного корня в рациональных числах на этапе компиляции.
Пример:
Создаём рациональное число 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;
};
sany
code C++ math templates
Вычисление квадратного корня в целых числах на этапе компиляции
пример 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;
};
sany
code C++
скомпилируется ли код и что выдаст программа?

#include <iostream>
using namespace std;

struct A
{
  A() { cout << __func__ << endl; }
  ~A() { cout << __func__ << endl; }
};

int main()
{
  A::A::A::A();
  return 0;
}
sany
C++ способ объявления неинициализованной ссылки: int &k = k; по адресу хранится ноль. В отличии от int &k = (int)0; на первый способ хоть ругается.
sany
C++ boost интересная штука boost::optional
есть функция, возвращающая найденное значение, что она должна возвращать, если ничего не нашла?
для понимания как пользоваться достаточно взглянуть примеры boost.org