Domanda

It's possible to iterate over a boost or std tuple, but can I iterate in an order determined at runtime, while still retaining type information?

Suppose my tuple was filled with objects of type 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;
}

I would like to be able to traverse the list of Foo types, calling their doit methods, but in an arbitrary order defined by, say, the value of the rank member.

È stato utile?

Soluzione

You will need to implement some type erasure in order to make this happen. Something along the lines of

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

There are other mechanisms you can apply which are functional, for example, and do not require modifying Foo, but they all boil down to the same principle- type erasure. I merely provided the simplest implementation of that erasure.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top