次のような構造体がいくつかあるとしましょう。
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;
}
};
ご覧のとおり、3 つの構造体すべてについて、その構造体のオブジェクトに対して 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()
また、これらの要素の 1 つを取得し、実行時に決定されるインデックスに基づいてその関数を実行したいとします。これを実現するには、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 ステートメントのコンパイラ生成ジャンプ リストは、自家製の関数ポインター ソリューションよりも効率的であると確信しています。