The following code compiles fine with g++ (GCC) 4.7.1 20120721
, but
fails with a recently build clang version 3.2 (trunk)
.
struct Y {};
struct X {
operator const Y() const { return Y(); }
};
void f(Y&& y) {}
int main()
{
f(X());
return 0;
}
Changing the conversion operator to operator Y() const
is sufficient
to make the code compile on both compilers.
Which compiler is actually standard compliant in this case? What does the standard actually say about this?
The verbatim error as requested:
bla.cpp:14:5: error: no viable conversion from 'X' to 'Y'
f(X());
^~~
bla.cpp:1:8: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'X' to
'const Y &' for 1st argument
struct Y {
^
bla.cpp:1:8: note: candidate constructor (the implicit move constructor) not viable: no known conversion from 'X' to
'Y &&' for 1st argument
struct Y {
^
bla.cpp:6:3: note: candidate function
operator const Y() const { return Y(); }
^
bla.cpp:10:12: note: passing argument to parameter 'y' here
void f(Y&& y) {}
^
EDIT: Unfortunately even adding the overload
void f(const Y&) {}
still makes clang choose the rvalue reference overload and so this breaks existing code that used to compile fine, e.g. with standard containers.