https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81952
Bug ID: 81952 Summary: copy elision used when constructor needs to be called Product: gcc Version: 7.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: barry.revzin at gmail dot com Target Milestone: --- >From StackOverflow (https://stackoverflow.com/q/45843428/2069064), a reduced example: #include <iostream> template <class T> struct opt { opt() { } opt(opt const& ) { std::cout << "1a\n"; } opt(opt&& ) { std::cout << "1b\n"; } template <class U> opt(U&& ) { std::cout << "2\n"; } }; struct foo { explicit operator opt<int>() { std::cout << "3\n"; return {}; } }; int main() { opt<int> o(foo{}); } This is direct-initialization of an object not of the same type, so we need to go through the constructors, the best of which is the template so this program should print 2. But instead, gcc elides this and just invokes the opt<int> conversion function and prints 3 (but not 1b, just 3).