功能模板专业化格式

ste*_*anB 30 c++ syntax templates template-specialization

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

template<> void doh::operator()<>(int i)
Run Code Online (Sandbox Code Playgroud)

这出现在SO问题中,有人提出之后有一些括号丢失operator(),但是我找不到解释.

如果它是表单的类型特化(完全特化),我理解其含义:

template< typename A > struct AA {};
template<> struct AA<int> {};         // hope this is correct, specialize for int
Run Code Online (Sandbox Code Playgroud)

但是对于功能模板:

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
Run Code Online (Sandbox Code Playgroud)

这适合这种情况?:

template<> void doh::operator()<>(bool b) {}
Run Code Online (Sandbox Code Playgroud)

示例代码似乎有效并且没有给出任何警告/错误(使用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);
}
Run Code Online (Sandbox Code Playgroud)

输出:

operator()(bool b)
template <> void operator()(int i)
Run Code Online (Sandbox Code Playgroud)

Joh*_*itb 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
}
Run Code Online (Sandbox Code Playgroud)

请注意,在标准术语中,specialization指的是使用显式特化和使用实例化生成的函数编写的函数,在这种情况下,我们必须使用生成的特化.specialization不仅仅是指使用明确专门化模板创建的函数,通常只使用它.

结论:GCC弄错了.Comeau,我也测试了代码,正确并发出诊断:

"ComeauTest.c",第16行:错误:"void doh::operator()(bool)"不是可以明确专门化的实体 template<> void doh::operator()(bool i)

请注意,它并没有抱怨模板的特殊化int(仅用于bool),因为它没有引用相同的名称类型:特化将具有的函数类型void(int),它与函数类型不同非模板成员函数,即void(bool).