(Этот вопрос является ответом на обсуждение в комментариях Шаблонная специализация шаблона переменной и вычитание типа .)
[temp.expl.spec] / 10 утверждает, что [ emphasis mine]:
Завершающий аргумент шаблона можно не указывать в template-id , указав явную специализацию шаблона функции , при условии, что она может быть выведена из типа аргумента функции . [Пример:
template<class T> class Array { /* ... */ };
template<class T> void sort(Array<T>& v);
// explicit specialization for sort(Array<int>&)
// with deduced template-argument of type int
template<> void sort(Array<int>&);
- конец примера]
Что явно относится к (полной) явной специализации foo(T)
в следующем примере:
#include <iostream>
template <typename T>
void foo(T) { std::cout << "primary\n"; }
template <>
void foo(int) { std::cout << "int\n"; }
// OK ^<int> deduced from template argument deduction
// in this _declaration_, as of [temp.expl.spec]/10
int main()
{
const int a = 42;
foo(a); // int
// OK, <int> deduced from template argument deduction.
}
Однако и для clang, и для G CC, для всех различных версий ISO C ++, которые я тестировал, это также применимо в примере, где нет аргументов функции в шаблоне функции, и где ее, скажем, шаблон типа Параметр присутствует только в качестве типа возврата шаблона функции:
#include <iostream>
template <typename T>
T bar() { std::cout << "primary\n"; return 0; }
template <>
int bar() { std::cout << "int\n"; return 42; }
// ^<int> deduced?
int main()
{
(void)bar<int>(); // int
// ^^^ OK, no template argument deduction.
}
Я немного запутался с термином "deduced" в приведенной выше цитате, поскольку он, как говорится, не относится к выводу в смысле типичного (вызов сайта / создания экземпляра) вывода аргумента шаблона, а скорее к выводу в контексте объявления специализации.
Вопрос:
- Где это охватывается в стандарте ISO C ++, что конечный аргумент шаблона в объявлении явной специализации шаблона функции с аргументом шаблона присутствует только в качестве рету Тип rn, может быть фактически опущен (выведен)?