【问题标题】:Traversing a C++ tuple in an order defined at runtime按照运行时定义的顺序遍历 C++ 元组
【发布时间】:2012-01-18 22:41:04
【问题描述】:

可以迭代 boost 或 std 元组,但我可以按照运行时确定的顺序进行迭代,同时仍保留类型信息吗?

假设我的元组中填充了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 成员的值定义的任意顺序。

【问题讨论】:

    标签: c++ templates c++11 tuples boost-tuples


    【解决方案1】:

    为了实现这一点,您需要实现一些类型擦除。类似于

    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;
    }
    

    您可以应用其他机制,例如,它们是功能性的,并且不需要修改 Foo,但它们都归结为相同的原则 - 类型擦除。我只是提供了该擦除的最简单实现。

    【讨论】:

    • 谢谢。我不清楚“呼叫”阶段将如何工作:在我对bases 进行排序之后,我有一个(FooBase *)vector,但我需要完整的类型才能调用doit(),不是吗?我也对虚函数的可移植性有一点担忧,并且对你提到的函数方法非常感兴趣。
    • @user643722: virtual 函数是完全可移植的,大大比支持 bar 的模板机制更便携。您需要完整类型才能调用doit(),但该类型会被虚函数“擦除”,然后在实际的doit() 主体中再次被识别。
    • 再次感谢。我可以制作(FooBase*) 的向量,我希望bases.push_back((FooBase*)&amp;get&lt;0&gt;(tup)); 将是一个开始。但是,一旦bases 的顺序改变了,我怎么能调用doit() 方法:我不知道每个(FooBase *) 指针的类型。
    • @user643722:因为它是virtual 方法?这样做的全部原因是因为您不必知道派生类型。它在运行时被抽象出来。
    • @user643722:因为FooBase*是一个指针,所以你使用bases[0]-&gt;doit();
    猜你喜欢
    • 2011-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-23
    • 1970-01-01
    • 2018-09-04
    相关资源
    最近更新 更多