Belloc
Belloc

Reputation: 6390

What is the purpose of the last sentence in [dcl.fct.spec]/4?

[dcl.fct.spec]/4:

In an explicit-specifier, the constant-expression, if supplied, shall be a contextually converted constant expression of type bool ([expr.const]). The explicit-specifier explicit without a constant-expression is equivalent to the explicit-specifier explicit(true). If the constant expression evaluates to true, the function is explicit. Otherwise, the function is not explicit. A ( token that follows explicit is parsed as part of the explicit-specifier.

What is the purpose of the last sentence above? Isn't this obvious from the first definition of the grammar term explicit-specifier given below?

explicit-specifier:

 explicit ( constant-expression )
 explicit 

Upvotes: 2

Views: 85

Answers (1)

user17732522
user17732522

Reputation: 76829

The following is valid:

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

//1 declares a constructor of A with parameter list /*...*/. This is allowed because the grammar for declarators allows adding extra parentheses in various places, e.g. around the declarator-id A.

So then there is a question of how

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

should be interpreted.

Before C++20 //2 would mean that we have the same constructor signature as in //1, but marked explicit, and the C++20 grammar without the sentence in question would still allow parsing it that way, while parsing (A) as part of the explicit-specifier wouldn't work, because () is not a valid declarator syntax and A is not an expression.

The sentence that you are asking about forces the second interpretation making this ill-formed. The proposal doesn't make a specific argument as to why, but I suppose it is meant to avoid mistakes, since something like

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

looks like explicit(A) was an explicit-specifier, although per the grammar itself, it wouldn't be parsed that way.

This is also mentioned as breaking change in [diff.cpp17.class]/1.

As far as I can tell, this only makes previously well-formed code ill-formed. I don't think there is any actual ambiguity without that sentence. The only code made ill-formed are declarations with extra parentheses around the declarator-id, which probably nobody uses in practice.

Upvotes: 6

Related Questions