(这个问题是评论中讨论的分支变量模板的模板特化和类型推导 https://stackoverflow.com/questions/61384251/template-specialization-of-variable-template-and-type-deduction.)
[温度解释规格]/10 https://timsong-cpp.github.io/cppwp/n4659/temp.expl.spec#10指出[emphasis mine]:
尾随一个模板参数 https://timsong-cpp.github.io/cppwp/n4659/temp.names#nt:template-argument
可以不指定 in the
模板 ID https://timsong-cpp.github.io/cppwp/n4659/temp.names#nt: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 和 GCC,对于我测试过的所有各种 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.
}
我对这个术语有点困惑“推论”在上面的引用中,afaics 并不是指典型(调用站点/实例化)模板参数推导意义上的推导,而是指专门化声明上下文中的推导。
问题:
- ISO C++ 标准中的哪些内容涵盖了尾随模板参数在显式函数模板特化的声明中,模板参数仅作为返回类型出现,实际上可以省略(推导)吗?