Running the code supplied in this question:
Why move return an rvalue reference parameter need to wrap it with std::move()?
#include <string>
#include <iostream>
#include <utility>
template<typename T>
class TD;
class Widget {
public:
explicit Widget(const std::string& name) : name(name) {
std::cout << "Widget created with name: " << name << ".\n";
}
Widget(const Widget& w) : name(w.name) {
std::cout << "Widget " << name << " just got copied.\n";
}
Widget(Widget&& w) : name(std::move(w.name)) {
std::cout << "Widget " << name << " just got moved.\n";
}
private:
std::string name;
};
Widget passThroughMove(Widget&& w) {
// TD<decltype(w)> wType;
// TD<decltype(std::move(w))> mwType;
return std::move(w);
}
Widget passThrough(Widget&& w) {
return w;
}
int main() {
Widget w1("w1");
Widget w2("w2");
Widget wt1 = passThroughMove(std::move(w1));
Widget wt2 = passThrough(std::move(w2));
return 0;
}
Yields different results depending on the compiler I use. When compiling using the latest Visual Studio (tried both C++14 and C++17) I get the following results:
Widget created with name: w1.
Widget created with name: w2.
Widget w1 just got moved.
Widget w2 just got moved. //<---
Ran and compiled this code online and the results were different. In the provided question the user also receives the same results:
Widget created with name: w1.
Widget created with name: w2.
Widget w1 just got moved.
Widget w2 just got copied. //<---
Why is w2 being moved when using Visual Studio and copied when using various different compilers?