[dcl.fct.spec]/4 中最后一句的目的是什么?

问题描述 投票:0回答:1

[dcl.fct.spec]/4:

显式说明符中,常量表达式(如果提供), 应为 bool 类型的上下文转换常量表达式 ([expr.const])。没有 的 显式说明符

explicit
常量表达式相当于显式说明符
explicit(true)
。如果常量表达式的计算结果为
true
,则 函数是显式的。否则,该函数不显式。一个
(
explicit
之后的标记被解析为 显式说明符

上面最后一句的目的是什么?从下面给出的语法术语 explicit-specifier 的第一个定义来看,这不是很明显吗?

显式说明符

 explicit ( constant-expression )
 explicit 
c++ syntax language-lawyer explicit
1个回答
6
投票

以下内容有效:

struct A {
    (A)(/*...*/); //1
};

//1
声明带有参数列表
A
/*...*/
的构造函数。这是允许的,因为声明符的语法允许在不同的地方添加额外的括号,例如围绕 declarator-id
A

那么就有一个如何的问题

struct A {
    explicit (A)(/*...*/); //2
};

应该被解释。

在 C++20 之前,

//2
意味着我们具有与
//1
中相同的构造函数签名,但标记为
explicit
,并且没有相关句子的 C++20 语法仍然允许以这种方式解析它,将
(A)
解析为 explicit-specifier 的一部分是行不通的,因为
()
不是有效的声明符语法,并且
A
不是表达式。

您所问的句子强制采用第二种解释,从而导致这种形式不正确。该提案没有具体说明原因,但我认为这是为了避免错误,因为类似

struct A {
    explicit(A) (/*...*/); //3
};

看起来

explicit(A)
是一个 显式说明符,尽管根据语法本身,它不会被这样解析。

这也被称为 [diff.cpp17.class]/1 中的重大更改。

据我所知,这只会使之前格式良好的代码变得格式错误。我认为如果没有这句话,就不存在任何实际的歧义。唯一格式错误的代码是在 declarator-id 周围带有额外括号的声明,在实践中可能没有人使用它。

© www.soinside.com 2019 - 2024. All rights reserved.