блочный неспециализированный шаблон с ++ - PullRequest
5 голосов
/ 04 августа 2011

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

template <typename T>
void foo(){}

template <>
void foo<int>(){}

int main(int argc, char* argv[]){
    foo<int>(); //ok
    foo<char>(); //Wrong - no specialized version for char.
}

Я не могу пропустить универсальную версию функции, потому что тогда компилятор говорит, что foo - это не шаблонная функция, когда я пытаюсь специализироваться.Я мог бы просто написать что-то, что не компилируется в обобщенную функцию, и добавить комментарий, объясняющий почему, но это было бы неинформативно.Что я хотел бы сделать, так это уметь напрямую вызывать компилятор с ошибкой типа «foo () не определен».

Ответы [ 2 ]

13 голосов
/ 05 августа 2011

Конечно: просто не определяйте его, и вы получите ошибку компоновщика, если попытаетесь его использовать:

template <typename T>
void foo(); // not defined

template <>
void foo<int>() { }

В качестве альтернативы, вы можете использовать некоторую вариацию статического утверждения, чтобы получить "приятнее "ошибка времени компиляции.Вот пример использования C ++ 0x static_assert.Обратите внимание, что вы должны сделать значение false зависимым от параметра шаблона, в противном случае static_assert может сработать при разборе шаблона.

template <typename T>
struct dependent_false { enum { value = false }; };

template <typename T>
void foo()
{
    static_assert(dependent_false<T>::value, "Oops, you used the primary template");
}

Обратите внимание, что обычно лучше не специализироватьшаблоны функций .Вместо этого лучше делегировать специализированный шаблон класса:

template <typename T>
struct foo_impl
{
    static_assert(dependent_false<T>::value, "Oops, you used the primary template");
};

template<>
struct foo_impl<int>
{
    static void foo() { }
};

template <typename T>
void foo()
{
    return foo_impl<T>::foo();
}
4 голосов
/ 05 августа 2011

Конечно, просто не предоставляйте определение для универсального шаблона по умолчанию.

...