`class template Example <int>;`语句对C++ 11意味着什么?

amn*_*amn 8 c++ templates c++11

我已经参考了cplusplus.com上的Explicit Template Instantiation文章,文章给出了以下示例:

template <typename T> class Example
{
public:
    Example( T test )
    {
        _data = test;
    }
    void setTest(T test)
    {
        _data = T;
    }
private:
    T _data;
};

class template Example<int>;
class template Example<float>;
class template Example<double>;
Run Code Online (Sandbox Code Playgroud)

除了我试图将一个类型分配给成员变量_data = T而不是我认为应该是什么之类的东西看起来像是一个遗漏错误_data = test- 我不明白的是最后3行声明或指示的是什么编译器要做什么?

我知道模板是什么,用它们构建程序,并且一般都知道它们的实例化和专业化.我对后两者的理解可能有一些漏洞,但我通常使用例如template class Example<int>;表单而不是片段中显示的那个来指示显式模板实例化.

我已经尝试使用编译片段g++ -std=c++11 -pedantic,它编译得很好而没有警告(我先纠正了_date = T上面的错误).

在我对一个相关问题的答案进行评论之后,我仍然不确定该片段中最后3行中的任何一行是模板特化还是实例化.

我还尝试在ISO发布C++ 11草案中找到相关的语法生成规则(一个允许template之后class),但空手而归.

Sha*_*our 10

我们可以从下面的godbolt 示例中看到,这是根据clang和MSVC的不正确形式,并查看关于显式实例化部分的草案标准部分[temp.explicit]我没有看到任何理由让gcc接受它.

我相信这篇文章"可能"的意思是:

template class Example<int>;
template class Example<float>;
template class Example<double>;
Run Code Online (Sandbox Code Playgroud)

这确实与gcc/clang/MSVC结合良好.

看起来像C++ 11这个语法是允许的,请参阅缺陷报告1707:没有嵌套名称说明符的elaborated-type-specifier中的模板(强调我的):

10.1.7.3 [dcl.type.elab]中详细说明类型说明符的语法部分内容如下:

elaborated-type-specifier:
    class-key nested-name-specifieropt templateopt simple-template-id
Run Code Online (Sandbox Code Playgroud)

允许使用template关键字而不使用嵌套名称说明符,例如结构模板S.这与template关键字的其他用法不一致.最好将生产分成两部分,只允许关键字遵循嵌套名称说明符,

....

因此,这使得一些更有意义与本评论-ansi引起一个警告.

另一位回答者提交了两份错误报告.

cppreference 有明确的显式实例化和这个SO问题显式实例化 - 何时使用?详细解释了为什么这是有用的.

另请注意,我们可以看到这篇Meta帖子:链接被更改为cppreference.com,该网站已知具有不正确的信息,并且通常社区更喜欢将cppreference作为可靠的C++参考.


cpp*_*ner 9

我在这看到两个错误:

  1. GCC将template关键字视为template消除歧义,因此认为它class template Example<int>等同于class Example<int>.这是不正确的,因为C++语法只允许template消除歧义器::,.或者->.(最初编写的C++ 11允许class template Example<int>,但这已由cwg 1707修复.)
  2. GCC错误地允许声明,如class Example<int>;.虽然class Example<int>;匹配simple-declaration的语法,但它无法满足[dcl.dcl]/5中的要求,该要求声明simple-declaration必须声明或重新声明某些内容(class/enumeration/enumerator/typedef/variable/function).

前者已报告为GCC bug 87781,后者为GCC bug 87783.

更新:GCC错误87781现在由r266285修复.