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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 18:03:44  来源:igfitidea点击:

Function template specialization format

c++templatessyntaxtemplate-specialization

提问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 specialized template<> 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).