C++ 函数模板专业化格式
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/937744/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Function template specialization format
提问by stefanB
What is the reason for the second brackets <> in the following function template:
以下函数模板中第二个括号 <> 的原因是什么:
template<> void doh::operator()<>(int i)
This came up in SO questionwhere it was suggested that there are brackets missing after operator(), however I could not find the explanation.
这出现在SO 问题中,有人建议在 之后缺少括号operator(),但是我找不到解释。
I understand the meaning if it was a type specialization (full specialization) of the form:
如果它是以下形式的类型专业化(完全专业化),我理解其含义:
template< typename A > struct AA {};
template<> struct AA<int> {}; // hope this is correct, specialize for int
However for function templates:
但是对于函数模板:
template< typename A > void f( A );
template< typename A > void f( A* ); // overload of the above for pointers
template<> void f<int>(int); // full specialization for int
Where does this fit into this scenarion?:
这在哪里适合这个场景?:
template<> void doh::operator()<>(bool b) {}
Example code that seems to work and does not give any warnings/error (gcc 3.3.3 used):
示例代码似乎可以工作并且没有给出任何警告/错误(使用 gcc 3.3.3):
#include <iostream>
using namespace std;
struct doh
{
void operator()(bool b)
{
cout << "operator()(bool b)" << endl;
}
template< typename T > void operator()(T t)
{
cout << "template <typename T> void operator()(T t)" << endl;
}
};
// note can't specialize inline, have to declare outside of the class body
template<> void doh::operator()(int i)
{
cout << "template <> void operator()(int i)" << endl;
}
template<> void doh::operator()(bool b)
{
cout << "template <> void operator()(bool b)" << endl;
}
int main()
{
doh d;
int i;
bool b;
d(b);
d(i);
}
Output:
输出:
operator()(bool b)
template <> void operator()(int i)
回答by Johannes Schaub - litb
I've looked it up, and found that it is specified by 14.5.2/2:
我查了一下,发现是14.5.2/2指定的:
A local class shall not have member templates. Access control rules (clause 11) apply to member template names. A destructor shall not be a member template. A normal (non-template) member function with a given name and type and a member function template of the same name, which could be used to generate a specialization of the same type, can both be declared in a class. When both exist, a use of that name and type refers to the non-template member unless an explicit template argument list is supplied.
本地类不应具有成员模板。访问控制规则(第 11 条)适用于成员模板名称。析构函数不应是成员模板。具有给定名称和类型的普通(非模板)成员函数和同名成员函数模板(可用于生成相同类型的特化)都可以在类中声明。当两者都存在时,除非提供了显式模板参数列表,否则使用该名称和类型是指非模板成员。
And it provides an example:
它提供了一个例子:
template <class T> struct A {
void f(int);
template <class T2> void f(T2);
};
template <> void A<int>::f(int) { } // non-template member
template <> template <> void A<int>::f<>(int) { } // template member
int main()
{
A<char> ac;
ac.f(1); //non-template
ac.f('c'); //template
ac.f<>(1); //template
}
Note that in Standard terms, specializationrefers to the function you write using an explicit specialization and to the function generated using instantiation, in which case we have to do with a generated specialization. specializationdoes not only refer to functions you create using explicitly specializing a template, for which it is often only used.
请注意,在标准术语中,specialization指的是使用显式特化编写的函数和使用实例化生成的函数,在这种情况下,我们必须使用生成的特化。specialization不仅指您使用显式专门化模板创建的函数,它通常只用于模板。
Conclusion: GCC gets it wrong. Comeau, with which i also tested the code, gets it right and issues a diagnostic:
结论:海湾合作委员会弄错了。Comeau,我也用它测试了代码,正确并发出诊断:
"ComeauTest.c", line 16: error:"void doh::operator()(bool)"is not an entity that can be explicitly specializedtemplate<> void doh::operator()(bool i)
"ComeauTest.c", line 16: error:"void doh::operator()(bool)"is not an entity that can be显式特化template<> void doh::operator()(bool i)
Note that it isn't complaining about the specialization of the template for int(only for bool), since it doesn't refer to the same name andtype: The function type that specialization would have is void(int), which is distinct from the function type of the non-template member function, which is void(bool).
请注意,它并没有抱怨 for int(仅 for bool)模板的特化,因为它不引用相同的名称和类型:特化将具有的函数类型是void(int),它不同于非模板成员函数,即void(bool).

