[Bug c++/66392] New: rejects-valid: copy-initialization through user-defined conversion sequence fails
filip.roseen at gmail dot com
gcc-bugzilla@gcc.gnu.org
Wed Jun 3 08:24:00 GMT 2015
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66392
Bug ID: 66392
Summary: rejects-valid: copy-initialization through
user-defined conversion sequence fails
Product: gcc
Version: 5.1.0
Status: UNCONFIRMED
Keywords: rejects-valid
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: filip.roseen at gmail dot com
Target Milestone: ---
Created attachment 35687
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=35687&action=edit
testcase.cpp - inaccurately rejected
There are many variants of the supplied testcase, but the following shall
compile due to the wording of `[dcl.init]p17` (and relevant sections) - `gcc`
inaccurately rejects the snippet:
struct B { };
struct A {
explicit A (A const&);
A (B const&);
};
int main () {
A x = B {}; // legal
}
---------------
testcase.cpp: In function ‘int main()’:
testcase.cpp:9:12: error: no matching function for call to ‘A::A(A)’
A x = B {}; // legal
^
testcase.cpp:5:12: note: candidate: A::A(const B&)
A (B const&);
^
testcase.cpp:5:12: note: no known conversion for argument 1 from ‘A’ to
‘const B&’
testcase.cpp:5:12: note: after user-defined conversion: A::A(const B&)
---------------
[ Note: `msvc`, `clang`, `icc` all accept the above snippet ]
---------------
In short the ISO C++ Standard says that if copy-initialization takes place
where the source type is not the same as the destination type, but there is a
user-defined conversion sequence that can convert the source type into the
destination type - such will be used to construct a temporary, and that
temporary will then be used to _direct-initialize_ the destination object.
It should be noted, as directly addressed in the standard wording, that
copy-elision may be used to skip the construction of the temporary object.
[ Note: it is important to note that the wording talks about "user-defined
conversion sequences", as such one must properly take into account usage of
`operator T`, where `T` is the destination type, in the source type which shall
yield the same described behavior as the attached testcase ]
------------------------------------------
Relevant part of `[dcl.init]p17`:
> Otherwise (i.e., for the remaining copy-initialization cases), user-defined
> conversion sequences that can convert from the source type to the destination
> type or (when a conversion function is used) to a derived class thereof are
> enumerated as described in [over.match.copy], and the best one is chosen through
> overload resolution ([over.match]). If the conversion cannot be done or is
> ambiguous, the initialization is ill-formed. The function selected is called
> with the initializer expression as its argument; if the function is a
> constructor, the call initializes a temporary of the cv-unqualified version of
> the destination type. The temporary is a prvalue. The result of the call (which
> is the temporary for the constructor case) is then used to direct-initialize,
> according to the rules above, the object that is the destination of the
> copy-initialization. In certain cases, an implementation is permitted to
> eliminate the copying inherent in this direct-initialization by constructing the
> intermediate result directly into the object being initialized; see
> [class.temporary], [class.copy]
More information about the Gcc-bugs
mailing list