30

以下函数模板中第二个括号 <> 的原因是什么:

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)
4

1 回答 1

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)

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 and type: 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).

于 2009-06-02T03:06:24.993 回答