代码之家  ›  专栏  ›  技术社区  ›  stefanB

函数模板专业化格式

  •  30
  • stefanB  · 技术社区  · 17 年前

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

    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)
    
    1 回复  |  直到 9 年前
        1
  •  31
  •   Johannes Schaub - litb    17 年前

    我查了一下,发现它是由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 指使用显式专门化编写的函数和使用实例化生成的函数,在这种情况下,我们必须使用生成的专门化。 专业化 不仅指您使用显式专门化模板创建的函数,它通常只用于模板。

    结论:GCC搞错了。Comeau,我也用它测试了代码,它做对了,并发出了一个诊断:

    "ComeauTest.c" "void doh::operator()(bool)" 不是一个实体 可以明确地专门化 template<> void doh::operator()(bool i)

    请注意,它并不是在抱怨模板的专门化 int (仅适用于 bool ),因为它不引用相同的名称 type:专门化的函数类型是 void(int) void(bool) .