Использование типа, переданного в качестве шаблона в C ++ - PullRequest
2 голосов
/ 17 марта 2010

Можно ли реально использовать тип, переданный в качестве шаблона для потока управления?Я хотел бы написать функцию, которая использует шаблоны, которая, в свою очередь, вызывает другую функцию, основанную на переданном типе:

template <class T> void test_function (T var)
{
    //Do stuff
    if (T == char) {
        bar (var);
    } else {
        foo (var);
    }
    //Do even more stuff
}

Если нет, мне придется вернуться к перечислениям ...

Редактировать: Все ответы до сих пор советуют мне использовать специализацию шаблонов.Я не был очень конкретным, но это то же самое, что вообще не использовать шаблоны, потому что для каждого отдельного типа есть отдельный вызов функции.

Ответы [ 5 ]

6 голосов
/ 17 марта 2010

Обычно для этого вы используете специализацию:

template<class T> void forward(T t) {
    // ...
}

template<> void forward<char>(char c) {
    // ...
}

template<class T> void test(T t) {
    forward<T>(t);
}

Это дает вам "ветвление во время компиляции" .

4 голосов
/ 17 марта 2010

Это возможно , но это почти никогда не хорошая идея. Лучшей идеей является просто выделить общие биты и обеспечить перегрузку для функции для этих конкретных типов, например

template <class T> void test_function_prologue (T var)
{
    //Do stuff
}

template <class T> void test_function_epilogue (T var)
{
    //Do even more stuff
}

template <class T> void test_function (T var)
{
    test_function_prologue(var);
    foo (var);
    test_function_epilogue(var);
}

void test_function (char var)
{
    test_function_prologue(var);
    bar (var);
    test_function_epilogue(var);
}
2 голосов
/ 17 марта 2010

Пока foo () принимает аргумент типа char и bar () принимает любой T, это будет возможно.В противном случае нет.Обе ветви должны быть компилируемыми для любого T, с которым вы создаете экземпляр шаблона, даже если одна ветвь никогда не берется.Если обе ветви не могут быть скомпилированы для любого T, у вас нет другого выбора, кроме как использовать ветвление во время компиляции (что предпочтительно в любом случае).

В противном случае вы можете использовать Идентификацию типа времени выполнения:

if (typeid(T) == typeid(char))

или проверка во время компиляции:

if (boost::is_same<T, char>::value)

, где is_same может быть реализовано как

template <class T, class U>
struct is_same { static const bool value = false; };

template <class T>
struct is_same<T, T> { static const bool value = true; };
1 голос
/ 17 марта 2010

Даже с вашим отредактированным ответом я все равно предложу специализацию шаблона. Вы просто создаете прокси-функцию, которая вызывает нужную функцию:

template <class T> void call_other_function(T var)
{
   foo(var);
}

template <> void call_other_function<char>(char var)
{
   bar(var);
}

template <class T> void test_function (T var)
{
    //Do stuff
    call_other_function(var);
    //Do even more stuff
}
1 голос
/ 17 марта 2010

Вы можете использовать шаблон специализации для этого. Это означает, что вы можете определить различные реализации для универсального void test_function (T) и конкретная void test_function (char)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...