类模板构造函数可以在c ++ 20中具有冗余的模板参数列表吗 [英] Can class template constructors have a redundant template parameter list in c++20

查看:106
本文介绍了类模板构造函数可以在c ++ 20中具有冗余的模板参数列表吗的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

据我所知,以下代码

template<typename T>
struct S {
    S<T>();
};

格式正确,即使< T>

但是,在gcc主干(而不是gcc10.2上)上,使用 -std = c ++ 20 ,这会产生错误:

However, on gcc trunk (but not on gcc10.2), with -std=c++20 this gives an error:

error: expected unqualified-id before ')' token
    3 |     S<T>();
                 ^

代码使用 -std = c ++ 20 在clang干线上编译。这是bug,还是c ++ 20中尚未在所有编译器中实现的重大更改?

The code compiles on clang trunk with -std=c++20. Is this a bug, or is this a breaking change in c++20 that is yet to be implemented in all compilers?

推荐答案

实际上发生了变化。它记录在C ++ 20草案的兼容性部分。

There was a change, in fact. It's documented in the compatibility section of the C++20 draft.


[diff.cpp17.class]

2 受影响的子句:[class.ctor]和[class.dtor]

更改:一个简单模板ID不再作为声明者有效,构造函数或析构函数的ID。

理性:删除可能容易出错的冗余选项。

对原始功能的影响:有效的C ++ 2017代码可能无法在此国际标准中进行编译。例如:

2 Affected subclauses: [class.ctor] and [class.dtor]
Change: A simple-template-id is no longer valid as the declarator-id of a constructor or destructor.
Rationale: Remove potentially error-prone option for redundancy.
Effect on original feature: Valid C++ 2017 code may fail to compile in this International Standard. For example:

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


具体来说,字词变化量是这样的:

Specifically, the wording delta is this:

n4659 -C ++ 17标准草案- [class.ctor]

n4659 - C++17 standard draft - [class.ctor]

1 构造函数没有名称。在构造函数的声明中,
声明符是形式为函数的声明符

1 Constructors do not have names. In a declaration of a constructor, the declarator is a function declarator of the form

ptr-declarator ( parameter-declaration-clause ) noexcept-specifier attribute-specifier-seq

其中ptr-declarator仅包含一个id表达式,一个可选属性- specifier-seq和可选的括号,并且id-expression具有以下形式之一:

where the ptr-declarator consists solely of an id-expression, an optional attribute-specifier-seq, and optional surrounding parentheses, and the id-expression has one of the following forms:


  • 在属于成员的成员声明中,类的规范,但不是朋友声明,id-expression是立即封闭类的注入类名称;

  • 在属于该成员的成员声明中-类模板的规范,但不是朋友声明,id表达式是
    a类名,用于命名
    立即封闭类模板的当前实例;或

n4861 -C ++ 20标准草案- [class.ctor]

n4861 - C++20 standard draft - [class.ctor]

1 构造函数由声明所引入,该声明的声明符是形式为
的函数声明符([dcl.fct])

1 A constructor is introduced by a declaration whose declarator is a function declarator ([dcl.fct]) of the form

ptr-declarator ( parameter-declaration-clause ) noexcept-specifier attribute-specifier-seq

其中ptr-declarator仅包含一个id表达式,
可选的attribute-specifier-seq和可选的
括号,并且id表达式具有以下形式之一:

where the ptr-declarator consists solely of an id-expression, an optional attribute-specifier-seq, and optional surrounding parentheses, and the id-expression has one of the following forms:


  • 在属于类或类模板的成员规范但不是朋友声明
    ([class.friend])的成员声明中,id表达式是注入的类名$紧邻的实体的b $ b([class.pre])或

看,措词改变了。现在,在声明类模板的构造函数时,C ++ 20需要注入的类名称。 S< T> 是一个简单的模板ID,用于命名专业化名称。在模板中,注入的类名称只是 S

As you can see, the wording changed. C++20 now requires the injected class name when declaring a constructor for a class template. S<T> is a simple template id that names a specialization. Inside a template, the injected class name is simply S.

这是解决 CWG 2237

这篇关于类模板构造函数可以在c ++ 20中具有冗余的模板参数列表吗的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆