C++ Logo


Advanced search

Re: Designated initializers in overload resolution for nested members

From: Phil <std-discussion_at_[hidden]>
Date: Tue, 17 Jan 2023 23:57:17 +0100

this might be related to https://wg21.link/cwg2169 <https://wg21.link/cwg2169>

Since it is not even clear(ly stated yet) for the non-nesting case, ...

> Am 16.01.2023 um 18:49 schrieb Johannes Schaub via Std-Discussion <std-discussion_at_[hidden]>:
> Hi!
> I was reading the spec and found that it appears to apply a "wording trick" here, to make a function viable but render the call illformed (as we know from several other cases, for example with lvalue references to bitfield, yet there the trick is more obvious):
> "[Note 1 <https://eel.is/c++draft/over.ics.list#note-1>:
> Aggregate initialization does not require that the members are declared in designation order. <https://eel.is/c++draft/over.ics.list#2.sentence-2>
> If, after overload resolution, the order does not match for the selected overload, the initialization of the parameter will be ill-formed ([dcl.init.list] <https://eel.is/c++draft/dcl.init.list>). <https://eel.is/c++draft/over.ics.list#2.sentence-3>"
> (this follows from the normative wording for the simple non-nesting case.. I take the note because it clears the air here and shows the intention).
> However, as [dcl.init.aggr] notes (and again it follows from the normative wording anyway), if a member is initialized by {...} again, then the rules of list initialization applies. Therefore I think that [dcl.init.aggr] applies constraints on the order of members indirectly:
> "[Note 3 <https://eel.is/c++draft/dcl.init.aggr#note-3>:
> If an initializer is itself an initializer list, the element is list-initialized, which will result in a recursive application of the rules in this subclause if the element is an aggregate. <https://eel.is/c++draft/dcl.init.aggr#4.2.sentence-4>— end note]"
> I take all this to mean that the nested case is to be treated differently than the non-nested case, if going by the letter of the spec, but the implementations I tried (gcc and clang) treat the followinig example as being ambiguous, rather than selecting "C<B>":
> struct A {
> int x; int y;
> };
> struct B {
> int y; int x;
> };
> template<typename T>
> struct C {
> T a;
> };
> void f(C<A> a);
> void f(C<B> b);
> int main() {
> f({{ .y = 1, .x = 2}});
> }
> --
> Std-Discussion mailing list
> Std-Discussion_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion

Received on 2023-01-17 22:57:28