C ++ / C ++ 11 - оператор переключения для вариационных шаблонов?

Допустим, у меня есть несколько структуров, подобных этому:

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

};

, как вы можете видеть, для всех трех структуров, я могу назвать дошутным () на объекте этой структуры и у него работают (Хотя это достигается по-другому для каждого структуры):

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(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-элементных) кортежи. Было бы очень удобно, если оператор коммутатора может быть автоматически сгенерирован на основе количества элементов в вариадическом шаблоне. Псевдокод:

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, который позволил бы мне достичь этого? Если нет, я знаю, что я могу, несомненно, взломать решение со списком указателей функций в шаблоне, но мне просто любопытно, если что-то вроде этого существует, поскольку было бы лучше подходит для моих целей. Я уверен, что сгенерированный компилятор выключателя компилятора, сгенерированный компилятор, будет более эффективным, чем у моего домашнего указателя функции.

17
задан nonoitall 11 September 2011 в 22:46
поделиться