C ++ Boost MPL: как избавиться от векторной и callnot внутренней функции? - PullRequest
2 голосов
/ 30 ноября 2011

Я изучаю Boost.MPL и только начинаю. Поэтому, пожалуйста, прости меня, если решение является obvios. Я смотрю на такой образец:

#include <boost/mpl/vector.hpp>
#include <boost/mpl/for_each.hpp>
#include <iostream>

using namespace std;

struct A
{
    template <class T>
    void    operator()(T t)
    {
        cout << typeid(T).name() << "\t" << t << endl;
    }

    template <class TypeVector>
    void    FooAll(void)
    {
        boost::mpl::for_each<TypeVector>(*this);
    }
};

void main(void)
{
    A   a;
    a.FooAll<boost::mpl::vector<int, float, long>>();
}

и не могу не задаться вопросом, как избавиться от boost::mpl::vector при вызове FooALL (превратить его в a.FooAll<int, float, long>();) и для каждого аргумента вызвать некоторую статическую / глобальную / или классовую внутреннюю функцию, а не *this, которая меня смущает?

1 Ответ

2 голосов
/ 01 декабря 2011

пожалуйста, посмотрите на реализацию Boost Tuple (решает аналогичную проблему).Основная идея заключается в том, что вы можете указать максимальное количество аргументов шаблона для вашего метода FollAll <...> () и предоставить типы по умолчанию для большинства из них.Вот набросок того, что я имею в виду

#include <boost/type_traits/is_same.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/push_back.hpp>

using boost::is_same;
using boost::mpl::eval_if;
using boost::mpl::vector;
using boost::mpl::push_back;

struct EmptyType {  };

struct A
{
  template<typename arg1, typename arg2=EmptyType, typename arg3=EmptyType, ..., typename argN=EmptyType>
  void    FooAll() {
      // reconstruct the type vector for easy manipulation later
      // Bolierplate code!
      typedef vector<arg>   vector_arg1;       
      typedef typename eval_if<is_same<arg2, EmptyType>,
                                vector_arg1,
                                push_back<vector_arg1, arg2> >::type  vector_arg2;
      typedef typename eval_if<is_same<arg3, EmptyType>,
                                vector_arg2,
                                push_back<vector_arg2, arg3> >::type  vector_arg3;
      //... rest of arguments
      typedef typename eval_if<is_same<argN, EmptyType>,
                                vector_arg(N-1),
                                push_back<vector_arg(N-1), argN> >::type  vector_argN;

      // now you can manipulate the reconstructed type vector
      Do_some_internal_stuff<vector_argN>::apply();
  }
}

Если вы хотите использовать «хай-тек», вы можете попробовать стандартную функцию C ++ 11 под названием Variadic Templates .Но убедитесь, что компиляторы, на которые вы ориентируетесь, уже поддерживают эту функцию.

С наилучшими пожеланиями, Марцин

...