在显式说明符中,常量表达式(如果提供), 应为 bool 类型的上下文转换常量表达式 ([expr.const])。没有 的 显式说明符
常量表达式相当于显式说明符explicit
。如果常量表达式的计算结果为explicit(true)
,则 函数是显式的。否则,该函数不显式。一个true
(
之后的标记被解析为 显式说明符。explicit
上面最后一句的目的是什么?从下面给出的语法术语 explicit-specifier 的第一个定义来看,这不是很明显吗?
显式说明符:
explicit ( constant-expression )
explicit
以下内容有效:
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 周围带有额外括号的声明,在实践中可能没有人使用它。