I have the following code:
#include <iostream>
using namespace std;
template <class T> class Foo {
public:
template <class U> void operator = (const U &u) {
cout << "generic copy assigment\n";
}
void operator = (const Foo<T> &f) {
cout << "specific copy assigment\n";
}
template <class U> void operator = (U &&u) {
cout << "generic move assigment\n";
}
void operator = (Foo<T> &&f) {
cout << "specific move assigment\n";
}
};
int main() {
Foo<int> i, j;
i = j;
return 0;
}
If this runs, it prints "generic move assignment", i.e. the compiler prefers the move over the copy. However, if I comment out the two move assignments:
template <class T> class Foo {
public:
template <class U> void operator = (const U &u) {
cout << "generic copy assigment\n";
}
void operator = (const Foo<T> &f) {
cout << "specific copy assigment\n";
}
};
the output is "specific copy assignment".
In other words, when the class is move-enabled, the generic move is selected over the specific one, whereas if the class is not move-enabled, the specific copy is selected over the generic one.
Is it a bug of Visual Studio 2010 or is this behavior defined in the c++0x specifications?
Your template is not a "generic move assignment". But it is a "perfect forwarder", except that in your case it doesn't forward. The rule in C++0x is that template argument deduction treats a parameter "T&&" specially: Lvalue arguments deduce T to ArgType&, and Rvalue arguments deduce it to ArgType. That way, an lvalue of type ArgType will yield to ultimate parameter type ArgType&, and an Rvalue will ultimately yield to ArgType&&.
In your case, the lvalue right hand side yields a deduced parameter type "Foo &", which perfectly well matches the lvalue argument.
The currently draft (n3126) forbids the compiler to use the template to perform the copy assignment (in a very confusingly worded paragraph), though. It depens on the resolution of issue 1080 whether that will change or not.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With