假设我有一些这样的结构:
struct MyStruct1 {
inline void DoSomething() {
cout << "I'm number one!" << endl;
}
};
struct MyStruct2 {
static int DoSomething() {
cout << "I'm the runner up." << endl;
return 1;
}
};
struct MyStruct3 {
void (*DoSomething)();
MyStruct3() {
DoSomething = &InternalFunction;
}
static void InternalFunction() {
cout << "I'm the tricky loser." << endl;
}
};
如您所见,对于所有三个结构,我可以在该结构的对象上调用 DoSomething() 并让它工作(尽管每个结构的实现方式不同):
MyStruct1 a;
MyStruct2 b;
MyStruct3 c;
a.DoSomething(); // works, calls Struct1's instance function
b.DoSomething(); // works, calls Struct2's static function, discards return value
c.DoSomething(); // works, calls Struct3's function pointer
现在,假设我将这些结构的任意选择放入一个元组中:
tuple<MyStruct2, MyStruct3, MyStruct2, MyStruct1> collection;
还假设我想采用其中一个元素并DoSomething()
根据在运行时确定的索引运行它的函数。为此,我可以使用 switch 语句:
switch(index) {
case 0: get<0>(collection).DoSomething(); break;
case 1: get<1>(collection).DoSomething(); break;
case 2: get<2>(collection).DoSomething(); break;
case 3: get<3>(collection).DoSomething(); break;
}
这工作得很好而且很花哨,但是当它需要处理多个不同排列(并且可能比 4 元素长得多)的元组时,它会变得非常乏味、重复和容易出错。如果可以根据可变参数模板中的元素数量自动生成 switch 语句,那将非常方便。伪代码:
template <typename... T>
void DoSomethingByIndex(int index, tuple<T...>& collection) {
switch(index) {
STATIC_REPEAT(sizeof...(T), X) {
case X: get<X>(collection).DoSomething(); break;
}
}
}
C++11 中是否有任何机制可以让我实现这一目标?如果没有,我知道我可以毫无疑问地将一个解决方案与模板中的函数指针列表组合在一起,但我只是好奇这样的东西是否存在,因为它更适合我的目的。我确信 switch 语句的编译器生成的跳转列表也会比我自制的函数指针解决方案更有效。