如何解决类模板构造函数可以在c ++ 20中具有冗余的模板参数列表吗
据我所知,以下code:
template<typename T>
struct S {
S<T>();
};
格式正确,即使构造函数的声明中的<T>
是多余的。
但是,在gcc中继上(但在gcc10.2上不是),如果使用-std=c++20
,则会出现错误:
error: expected unqualified-id before ')' token
3 | S<T>();
^
code在-std=c++20
的clang干线上编译。这是一个错误,还是c ++ 20中一项尚未在所有编译器中实现的重大更改?
解决方法
实际上有一个变化。 C ++ 20草案的兼容性部分对此进行了记录。
[diff.cpp17.class]
2 受影响的条款:[class.ctor]和[class.dtor]
更改:simple-template-id不再有效,不能用作构造函数或析构函数的声明符ID。
合理:删除可能容易出错的选项,以实现冗余。
对原始功能的影响:有效的C ++ 2017代码可能无法在此国际标准中进行编译。例如:template<class T> struct A { A<T>(); // error: simple-template-id not allowed for constructor A(int); // OK,injected-class-name used ~A<T>(); // error: simple-template-id not allowed for destructor };
具体来说,措辞delta是这样的:
n4659 -C ++ 17标准草案- [class.ctor]
1构造函数没有名称。在构造函数的声明中, 声明符是形式的函数声明符
ptr-declarator ( parameter-declaration-clause ) noexcept-specifier attribute-specifier-seq
其中ptr-declarator仅由一个id表达式,一个可选的attribute-specifier-seq和可选的括号组成,并且id-expression具有以下形式之一:
- 在属于类的成员规范但不属于朋友声明的成员声明中,id-expression是立即封闭的类的注入类名称;
- 在属于类模板的成员规范但不是朋友声明的成员声明中,id-expression为 一个类名,用于命名当前实例化 立即封闭类模板;或
n4861 -C ++ 20标准草案- [class.ctor]
1构造函数由一个声明引入,该声明的声明符是 形式的函数声明符([dcl.fct])
ptr-declarator ( parameter-declaration-clause ) noexcept-specifier attribute-specifier-seq
其中ptr-declarator仅由id表达式, 可选的attribute-specifier-seq和可选的环境 括号,并且id表达式具有以下形式之一:
- 在成员声明中,该成员声明属于类或类模板的成员规范,但不是朋友声明 ([class.friend]),id表达式是注入的类名 ([class.pre])的直接封闭实体或
如您所见,措辞发生了变化。现在,在声明类模板的构造函数时,C ++ 20需要注入的类名称。 S<T>
是一个简单的模板ID,用于指定专业名称。在模板内部,注入的类名称仅为S
。
这是寻址CWG 2237的一部分。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。