"类模板示例<int>;"语句对 C++11 是什么意思?
What does `class template Example<int>;` statement mean with 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草案中找到相关的语法生成规则(在class
之后允许template
(,但没有找到。
我们可以从下面的godbolt示例中看出,根据clang和MSVC,这是不正确的,并且查看显式实例化部分[temp.extic]的标准草案部分,我看不出gcc接受它的任何理由。
我相信这篇文章"可能"的意思是:
template class Example<int>;
template class Example<float>;
template class Example<double>;
并且这确实是用gcc/clang/MSVC很好地形成的。
看起来在C++11之前,这种语法是允许的,请参阅缺陷报告1707:没有嵌套名称说明符的详细类型说明符中的模板(emphasis mine(:
10.1.7.3中详细说明的类型说明符的语法[dcl.type.elab]部分读取
elaborated-type-specifier: class-key nested-name-specifieropt templateopt simple-template-id
这允许在没有嵌套的名称说明符,例如结构模板S。这是与template关键字的其他用法不一致。可能是最好将生产一分为二,只允许关键字遵循嵌套的名称说明符
因此,-ansi
导致警告的注释更有意义。
另一个回答者提交了两份错误报告。
cppreference对显式实例化有很好的假设,这个SO问题是显式实例化——什么时候使用它?解释了为什么这很有用的更多细节。
另请注意,我们可以看到这篇Meta帖子:链接被更改为cppreference.com,该网站已知有不正确的信息,通常社区更喜欢将cppreference作为一个可靠的C++参考。
我在这里看到两个错误:
- GCC将这里的
template
关键字视为template
消歧器,从而认为class template Example<int>
等价于class Example<int>
。这是不正确的,因为C++语法只允许template
消歧器在::
、.
或->
之后(最初编写的C++11允许class template Example<int>
,但这已被cwg 1707修复。( - GCC错误地允许
class Example<int>;
这样的声明。尽管class Example<int>;
与简单声明的语法匹配,但它未能满足[dcl.dcl]/5中的要求,即简单声明必须声明或重新声明某个东西(class/enumeration/enumerator/typedef/variable/function(
前者被报告为GCC错误87781,后者被报告为GC错误87783。
更新:GCC错误87781现已由r266285修复。
- 我的简单if-else语句是如何无法访问的代码
- 有一个打印语句的函数是一种糟糕的编程实践吗
- 线程,如果else语句,都是错误的上下文切换后,会发生什么
- 为什么是0;C++中的有效语句
- MSVC是否支持C++11样式的属性而不是__declspec
- 创建LinkedList退出,返回代码为-11(SIGSEGV)
- 我可以将一个用clang c++11编译的对象与另一个用c++17编译的对象链接起来吗
- 继承:构造函数,初始化C++11中基类的类C数组成员
- Insert函数不适用于2 if语句C++
- If语句未被求值C++
- C++嵌套if语句,基本货币交换
- 多个If语句与使用逻辑运算符计算条件的单个语句的比较
- "类模板示例<int>;"语句对 C++11 是什么意思?
- C++11 是否保证 return 语句中的局部变量将被移动而不是复制?
- C++11 标准中的哪些条款允许我消除下面“A::operator-()”中“返回”语句中的“A”
- 返回语句中的C++11显式转换运算符/构造函数
- C++11:基于范围的 for 语句:"range-init"生命周期?
- 从if语句中初始化C++11线程
- 是否有任何(方便的)方法可以在 C++11 "foreach"语句中检索当前迭代 #?
- c++ 11标准中这个语句的含义是什么?