首页 > 解决方案 > 什么是`class template Example;` 语句对 C++11 意味着什么?

问题描述

我在cplusplus.com被称为“显式模板实例化”,它给出了以下示例:

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>;

除了对我来说似乎是一个遗漏错误,其中一个类型被尝试分配给一个成员变量——_data = T而不是我认为应该的_data = test——我不明白最后 3 行声明或指示什么编译器要做的,究竟是什么?

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

我尝试使用编译代码段g++ -std=c++11 -pedantic,它编译得很好并且没有警告(我_date = T首先更正了上面的错误)。

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

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

标签: c++c++11templates

解决方案


我们可以从下面的 godbolt示例中看到,根据 clang 和 MSVC,这是格式错误的,并且查看Explicit instantiation section [temp.explicit]的标准草案部分,我认为 gcc 没有任何理由接受它。

我相信鉴于该主题,文章“可能”的含义是:

template class Example<int>;
template class Example<float>;
template class Example<double>;

这确实与 gcc/clang/MSVC 格式良好

看起来在 C++11 之前这种语法是允许的,请参阅缺陷报告 1707:没有嵌套名称说明符的详细类型说明符中的模板强调我的):

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

elaborated-type-specifier:
    class-key nested-name-specifieropt templateopt simple-template-id

允许在没有嵌套名称说明符的情况下使用模板关键字,例如 struct template S。这与模板关键字的其他用途不一致。最好将产生式分成两部分,并且只允许关键字跟随在嵌套名称说明符之后,

……

因此,对于导致警告的此评论,这更有意义。-ansi

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

cppreference对 Explicit instantiation和这个 SO question Explicit instantiation - when it is used 有很好的讨论。解释更多细节为什么这很有用。

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


推荐阅读