【发布时间】:2014-08-17 21:51:20
【问题描述】:
考虑以下具有显式特化的函数模板。
template<typename T>
void f(T);
template<>
void f<int>(int i) { std::cout << "f() chose int\n"; ++i; }
template<>
void f<const int&>(const int&) { std::cout << "f() chose const int&\n"; }
第一个特化可以被隐式实例化。第二个不能,即使第一个专业化不存在。这与函数重载的规则不同,其中采用int 或const int& 的函数可以正常工作(链接示例中的g())。
提供int 的专用化示例。有效。
http://coliru.stacked-crooked.com/a/1680748749f36631
只有const int& 的特化可用的示例。编译但链接失败。
http://coliru.stacked-crooked.com/a/ab8b068d3f807837
为什么模板类型推导以这种方式工作,为什么选择以这种方式工作?另一种方法是模板类型推导表现得像函数重载。
我的理解是,对于重载函数,编译器已经知道所有可用的选项,但是对于模板,编译器必须首先决定要查找的内容,然后查看它是否可以实例化。如果是这种情况,那么要求编译器搜索类型的合格变体是不合理的要求吗?
【问题讨论】:
-
“不编译。”它确实编译。它不链接。无论如何,我认为你在这里得到的只是猜测。我可以自己猜测,但我认为这不会有帮助。
-
关于编译与链接的正确性,将编辑。有时,SO 上的人们知道似乎不可能知道的事情。我充满希望。
-
对不起,一定是看错了。
-
?
auto x = &f<const int&>;隐式实例化第二个特化。 -
实例化是从模板构建函数/类的过程。当您为
T == int实例化模板template<class T> void foo(T);时,您将创建一个名为foo<int>的函数。表达式&foo<int>使用函数的地址,因此该函数必须存在,因此它被实例化(如果它还不存在)。您没有像template void foo<int>(int);那样显式请求实例化,因此实例化是隐式的。
标签: c++ templates type-deduction