Created on 2020-11-20.00:00:00 last changed 48 months ago
It appears that P1787R6 has inadvertently changed the rules for where default arguments can be (re-)declared for a parameter. Consider:
namespace N { void f(int a, int b = 1); } void N::f(int a = 1, int b) {} // valid before P1787R6, invalid afterwards void N::f(int a, int b = 2) {} // invalid before P1787R6, valid afterwards, // but this default argument will either never be used or will make any call using it ill-formed (unclear which)
Subclause 9.3.4.7 [dcl.fct.default] paragraph 4 specifies:
For non-template functions, default arguments can be added in later declarations of a function that inhabit the same scope. Declarations that inhabit different scopes have completely distinct sets of default arguments. ...
The problem is that the out-of-line declaration of N::f inhabits the global namespace scope, not the scope of namespace N.
A similar problem exists for inheriting array bounds per 9.3.4.5 [dcl.array] paragraph 8:
Furthermore, if there is a reachable declaration of the entity that inhabits the same scope in which the bound was specified, an omitted array bound is taken to be the same as in that earlier declaration, and similarly for the definition of a static data member of a class.
Possible resolution:
Change in 6.4.1 [basic.scope.scope] paragraph 2 as follows:
... The host scope of a declaration is the inhabited scope if that scope is a block scope and the target scope otherwise. An entity belongs to a scope S if S is the target scope of a declaration of the entity.
Change in 9.3.4.5 [dcl.array] paragraph 8 as follows:
Furthermore, if there is a reachable declaration of the entity thatinhabitshas the same host scope in which the bound was specified, an omitted array bound is taken to be the same as in that earlier declaration, and similarly for the definition of a static data member of a class.
Change in 9.3.4.7 [dcl.fct.default] paragraph 4 as follows:
For non-template functions, default arguments can be added in later declarations of a function thatinhabithave the same host scope. Declarations thatinhabithave different host scopes have completely distinct sets of default arguments. ...
Change in 9.3.4.7 [dcl.fct.default] paragraph 9 as follows:
When an overload set contains a declaration of a functionthat inhabits awhose host scope is S, any default argument associated with any reachable declarationthat inhabitswhose host scope is S is available to the call.
Change in 12.2.4.1 [over.match.best.general] paragraph 4 as follows:
If the best viable function resolves to a function for which multiple declarations were found, and if any two of these declarationsinhabithave different host scopes and specify a default argument that made the function viable, the program is ill-formed. [ Example: ...void use() { f(3); // OK, default argument was not used for viability f(); // error: found default argument twice }int g(int, int = 0, int = 0); void h() { using ::g; int g(int, int, int = 1); int a = g(0); // OK, block scope declaration does not make the function viable; //uses default arguments of declaration whose host scope is the global namespace }-- end example ]
History | |||
---|---|---|---|
Date | User | Action | Args |
2020-11-20 00:00:00 | admin | create |