2011-11-30 55 views
2

我正在学习Boost.MPL,我刚刚开始。所以如果解决方案是明显的,请原谅我。我看这样的例子:C++ Boost MPL:如何摆脱向量和callnot内部函数?

#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>>(); 
} 

,并不能帮助,但不知道如何调用FooALL(把它变成a.FooAll<int, float, long>();)时摆脱boost::mpl::vector并为每个参数调用一些静态/全球/或类的内部函数,而不是*this这让我困惑?

回答

2

请看看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(); 
    } 
} 

如果你想要去的“高科技”你可以尝试命名Variadic Templates一个C++ 11标准功能的草图。但请确保您所定位的编译器已支持此功能。

最好的问候, 马辛

+0

@ user1072853我已经更新了更多的细节的例子。我无法访问编译器,因此请仅将此代码视为草图。 – Marcin