2012-01-18 61 views
2

可以迭代boost或std元组,但是我可以在运行时按照确定的顺序迭代,同时仍保留类型信息?以运行时定义的顺序遍历C++元组

假设我的元组中弥漫着Foo类型的对象:

#include <tuple> 

using namespace std; 

template <typename ...> void bar(); // Definition omitted. 

template <typename ... Ts> 
struct Foo { 
    void doit() { bar<Ts...>(); } 
    int rank; 
}; 

int main(int argc, char *argv[]) 
{ 
    auto tup = make_tuple(Foo<int,double>(), 
         Foo<bool,char,float>()); 
    get<0>(tup).rank = 2; 
    get<1>(tup).rank = 1; 
    return 0; 
} 

我想是能够穿越Foo类型列表中,调用它们doit方法,但通过定义的任意顺序,说,rank成员的值。

回答

3

您需要实施一些类型的擦除才能实现此目的。沿

template <typename ...> void bar(); // Definition omitted. 

struct FooBase { 
    virtual void doit() = 0; 
    int rank; 
}; 

template <typename ... Ts> 
struct Foo : public FooBase { 
    void doit() { bar<Ts...>(); } 
}; 

int main(int argc, char *argv[]) 
{ 
    auto tup = make_tuple(Foo<int,double>(), 
         Foo<bool,char,float>()); 
    get<0>(tup).rank = 2; 
    get<1>(tup).rank = 1; 
    std::vector<FooBase*> bases; 
    // fill bases 
    // sort 
    // call 
    return 0; 
} 

东西线有你可以申请其他机制它们的功能,例如,不需要修改富,但他们都归结到同一个principle-类型擦除。我只是提供了最简单的删除操作。

+0

Thankyou。我不清楚“调用”阶段是如何工作的:在我对'bases'进行排序后,我有一个'(vector)'(FooBase *)',但我需要全部类型来调用'doit()',没有?我也对虚拟功能的可移植性有所担忧,并且对你提到的功能方法非常感兴趣。 – user2023370 2012-01-18 23:15:57

+0

@ user643722:'虚拟'功能完全可移植,*极大地超过了为'bar'提供动力的模板机器。你需要完整的类型来调用'doit()',但是这个类型被虚函数“擦除”,然后在实际的'doit()'体中再次被知道。 – Puppy 2012-01-19 00:04:39

+0

再次感谢。我可以创建'(FooBase *)'的向量,我期望'bases.push_back((FooBase *)&得到<0>(tup));''但是,一旦'bases'的排序已被改变,我怎样才能调用'doit()'方法:我不知道每个'(FooBase *)'指针的类型。 – user2023370 2012-01-19 10:58:46