Hannes Hauswedell
2017-05-18 13:47:00 UTC
Hi everyone,
I have stumbled about this peculiar behaviour of clang and gcc:
https://godbolt.org/g/6IhJlV
That is, if we have A and B, and B has a user defined conversion operator
for A, than both of these should work:
B b;
A a1(b); // (1)
A a2{b}; // (2)
Why should they work?
Common sense:
* IIANM conversion used to be independent of whether it happens at the
target (via constructor) or via the source (user defined conversion
operator).
* with the introduction of explicit conversion operators in c++11 this
has become even more so
Standard:
* (1) is plain old behaviour
* (2) http://eel.is/c++draft/dcl.init.list#3.8
Do they work?
* (1) of course
* (2) works if A is a non-aggregate class type, because
http://eel.is/c++draft/dcl.init.list#3.8
* (2) fails if A is an aggregate class type, because the compiler picks
http://eel.is/c++draft/dcl.init.list#3.3 instead of
http://eel.is/c++draft/dcl.init.list#3.8
From my POV this behaviour is confusing, because we recommend people use
brace-initialization more routinely than parenthesis-initialization now and
aggregate initialization should add flexibility, right? :)
Or did I miss something and there is some benefit to (2) not working for
aggregate types?
Thanks and regards,
Hannes Hauswedell
P.S: for reference here the small discussion started over at cppreference
about this:
http://en.cppreference.com/w/Talk:cpp/language/direct_initialization
I have stumbled about this peculiar behaviour of clang and gcc:
https://godbolt.org/g/6IhJlV
That is, if we have A and B, and B has a user defined conversion operator
for A, than both of these should work:
B b;
A a1(b); // (1)
A a2{b}; // (2)
Why should they work?
Common sense:
* IIANM conversion used to be independent of whether it happens at the
target (via constructor) or via the source (user defined conversion
operator).
* with the introduction of explicit conversion operators in c++11 this
has become even more so
Standard:
* (1) is plain old behaviour
* (2) http://eel.is/c++draft/dcl.init.list#3.8
Do they work?
* (1) of course
* (2) works if A is a non-aggregate class type, because
http://eel.is/c++draft/dcl.init.list#3.8
* (2) fails if A is an aggregate class type, because the compiler picks
http://eel.is/c++draft/dcl.init.list#3.3 instead of
http://eel.is/c++draft/dcl.init.list#3.8
From my POV this behaviour is confusing, because we recommend people use
brace-initialization more routinely than parenthesis-initialization now and
aggregate initialization should add flexibility, right? :)
Or did I miss something and there is some benefit to (2) not working for
aggregate types?
Thanks and regards,
Hannes Hauswedell
P.S: for reference here the small discussion started over at cppreference
about this:
http://en.cppreference.com/w/Talk:cpp/language/direct_initialization
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-discussion+***@isocpp.org.
To post to this group, send email to std-***@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-discussion/.