2016-04-06 3 views
2

У меня есть такой код:Можно ли зацикливать параметры шаблона?

template <typename T1, 
      typename T2 = void, 
      typename T3 = void, 
      typename T4 = void, 
      typename T5 = void> 
std::set<std::type_info const*> MyClass<T1,T2,T3,T4,T5>::get_types() 
{ 
    std::set<std::type_info const*> t; 
    t.push_back(&typeid(T1)); 
    if(typeid(T2) != typeid(void)) 
     t.push_back(&typeid(T2)); 
    else 
     return; 
    if(typeid(T3) != typeid(void)) 
     t.push_back(&typeid(T3)); 
    else 
     return; 
    if(typeid(T4) != typeid(void)) 
     t.push_back(&typeid(T4)); 
    else 
     return; 
    if(typeid(T5) != typeid(void)) 
     t.push_back(&typeid(T5)); 
    else 
     return; 
} 

Есть ли способ, чтобы сделать петлю над типами шаблонов T2 для T5, чтобы избежать избыточного кода?

Примечание: Я не использую C++ 11. Я использую boost.

+0

Check [это] (HTTP: // stackoverflow.com/questions/1198260/iterate-over-tuple). Дублировать? – norisknofun

ответ

1

Да, вы можете с Boost MPL используя возможности boost::mpl::vector и boost::mpl::for_each как на примере ниже:

Live Demo

Код:

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

template <typename T> 
struct wrap {}; 

class Bar { 
    std::vector<std::type_info const*> &types; 
public: 
    Bar(std::vector<std::type_info const*> &types_) : types(types_) {} 
    template<typename T> void operator()(wrap<T>) const { 
    if(typeid(T) != typeid(void)) types.push_back(&typeid(T)); 
    } 
}; 

template<typename T1, typename T2 = void, typename T3 = void, typename T4 = void, typename T5 = void> 
struct Foo { 
    std::vector<std::type_info const*> get_types() const { 
    std::vector<std::type_info const*> out; 
    boost::mpl::for_each<boost::mpl::vector<T1, T2, T3, T4, T5>, wrap<boost::mpl::placeholders::_1> >(Bar(out)); 
    return out; 
    } 
}; 

int main() { 
Foo<int, long, double> foo; 
std::vector<std::type_info const*> types = foo.get_types(); 

for(int i(0), isz(types.size()); i < isz; ++i) { 
    std::cout << types[i]->name() << std::endl;  
} 
} 
1

Если вы уже используете boost, вы должны использовать контейнеры boost::mpl::* как ваши списки типов. Чем вы можете параметризовать свой шаблон с таким списком и использовать возможности mpl для обработки списков типов.