I'm curious about why I can't compile the following code.
It's nonsense code (I know), but I originally faced the problem in some other code using templates with perfect forwarding and such.
I managed to narrow the problem down to std::move
/ std::forward
/ std::remove_reference
, and I'm curious why it needs a temporary in the first place...
#include <utility>
#include <stdio.h>
struct Foo {
Foo(Foo&& other) {
printf("Foo::(Foo&&) %p\n", this);
}
Foo() {
printf("Foo::() %p\n", this);
}
~ Foo() {
printf("Foo::~Foo() %p\n", this);
}
};
void test(Foo&& t)
{
// OK: Works fine and "f1" is is constructed with Foo::Foo(Foo&& other)
// Foo f1 = std::move(t);
// ERROR: Here it is trying to bind a temporary Foo to a non-const lvalue
// I can't figure out why it needs to create a temporary.
Foo& f2 = std::move(t);
}
int main()
{
Foo foo;
test(std::move(foo));
}
Compiling with Clang (3.7), it gives me the following error:
23 : error: non-const lvalue reference to type 'Foo' cannot bind to a temporary of type 'typename std::remove_reference<Foo &>::type' (aka 'Foo')
Foo& f2 = std::move(t);
^ ~~~~~~~~~~~~
1 error generated.
Compilation failed
I understand I can't bind a temporary to a non-const
reference, and there are plenty of questions answering why that is not allowed.
I would expect the code to just carry a reference to foo
in main
up to Foo& f2
, thus not needing a temporary.
Visual Studio accepts the code, but GCC and Clang fail to compile it; although Visual Studio is not as strict of course.