第二个括号<>的原因是什么?在以下函数模板中:
template<> void doh::operator()<>(int i)
这出现在SO question,其中有人建议在operator()
之后缺少括号,但我找不到解释。
如果它是表格的类型专业化(完全专业化),我理解其含义:
template< typename A > struct AA {};
template<> struct AA<int> {}; // hope this is correct, specialize for int
但是对于功能模板:
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
这适合这种情况?:
template<> void doh::operator()<>(bool b) {}
示例代码似乎有效并且没有给出任何警告/错误(使用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);
}
输出:
operator()(bool b)
template <> void operator()(int i)
答案 0 :(得分:31)
我查了一下,发现它是由14.5.2 / 2指定的:
本地类不应具有成员模板。访问控制规则(第11节)适用于成员模板名称。析构函数不应是成员模板。具有给定名称和类型的普通(非模板)成员函数和具有相同名称的成员函数模板(可用于生成相同类型的特化)都可以在类中声明。如果两者都存在,则除非提供显式模板参数列表,否则使用该名称和类型将引用非模板成员。
它提供了一个例子:
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
}
请注意,在标准术语中,specialization
是指使用显式特化和使用实例化生成的函数编写的函数,在这种情况下,我们必须使用生成的特化。 specialization
不仅引用您使用明确专门化模板创建的函数,而且通常仅使用它。
结论:GCC弄错了。 Comeau,我也测试了代码,使其正确并发出诊断信息:
"ComeauTest.c"
,第16行:错误:"void doh::operator()(bool)"
不是实体 可以明确专业化template<> void doh::operator()(bool i)
请注意,它没有抱怨int
的模板专门化(仅适用于bool
),因为它没有引用相同的名称和 type:特化所具有的函数类型是void(int)
,它与非模板成员函数的函数类型void(bool)
不同。