Поиск во время компиляции из целого числа в тип через шаблоны C ++ - PullRequest
1 голос
/ 29 мая 2011

Есть ли способ реализовать словарь типов времени компиляции через шаблоны C ++? например если у меня есть несколько классов, подобных этим:

class ProtocolMajor1Minor2   { ... };
class ProtocolMajor4Minor3   { ... };
...
class ProtocolMajor12Minor21 { ... };

... есть ли способ использовать шаблоны C ++, которые позволили бы мне сделать что-то вроде этого:

void foo(int majorVersion, int minorVersion)
{
    LookupMap<majorVersion,minorVersion>::innertype *specific = 
        new LookupMap<majorVersion,minorVersion>::innertype;
    return specific->FunctionalityFoo();
}

В случае, если неясно, LookupMap действует так, как говорит само имя: учитывая два целочисленных параметра (старшую и младшую версии протокола), предполагается, что он обеспечивает конкретный тип протокола, который мне нужен, через «черту» innerType.

Я не могу использовать препроцессор для создания функции "foo" в качестве макроса (используя ## или #) по двум причинам: (а) она большая, не такая, как в этом примере, и я не хочу огромная функция, закодированная как макрос, и (b) сопоставления именования не являются прямыми (т. е. основная версия A и вспомогательная версия B не указывают на класс «ProtocolMajorAMinorB».

Вы также можете подумать, что «FunctionalityFoo» должен быть членом базового типа: Вы правы, но это код, сгенерированный из устаревших генераторов кода, то есть неприкасаемый. На самом деле существует множество функций, таких как «FunctionalityFoo», сгенерированных для каждой комбинации (главных, второстепенных), и я не хочу создавать лестницы if / then / else для каждой из них.

Я попробовал специализацию шаблонов, но не смог найти работающий синтаксис.

Есть ли способ сделать это с помощью шаблонов?

1 Ответ

2 голосов
/ 29 мая 2011

Нет, шаблоны построены во время компиляции, поэтому вы не можете использовать переменные в качестве аргументов шаблона.Чтобы это работало, вам нужно сделать что-то вроде этого (т.е. не использовать переменные, предоставляемые во время выполнения):

template <int A, int B>
struct LookupMap { };

template <>
struct LookupMap<1, 2> { typedef Type1_2 innertype; };

// ...
template <int A, int B>
sometype foo() {
    typedef typename LookupMap<A, B>::innertype T;
    T* ptr = new T; // also, this leaks, use a smart pointer or something
    return ptr->something();
}

// when used
foo<1, 2>();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...