Here's the compiler splash screen (for version etc.):
C:\Program Files\Microsoft Visual Studio 10.0\VC>cl.exe
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.30319.01 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.
usage: cl [ option... ] filename... [ /link linkoption... ]
I have a base class (which is a template), imagine it's:
template <typename T>
class Base {
public:
Base<T> & operator = (const Base<T> &);
Base<T> & operator = (Base<T> &&);
};
I then have a derived class which doesn't reimplement operator =
in any way.
If I do the following:
Derived<int> derived;
derived=Derived<int>();
the operator =
which accepts an lvalue is called on the second line.
If I go into the definition of Derived<T>
and add the following:
template <typename T>
Derived<T> & Derived<T>::operator = (Derived<T> && other) {
Base<T>::operator=(static_cast<Base<T> &&>(other));
return *this;
}
The operator =
which accepts an rvalue is called.
This behaviour persists even if I also implement the operator =
which takes an lvalue (in much the same manner).
For lack of a better phrase: What gives?
Am I misunderstanding C++ or is this not how it's supposed to work?
MSVC never generates implicit move construction/assignment. See http://msdn.microsoft.com/en-us/library/dd293668.aspx .
The reason is that implicit move semantics have undergone many changes during standard elaboration, and the final consensus was not here at the time MSVC10 was finished.
Bottom line: you have to declare explicitly every move constructor / move assignment operator you'd like to use by hand. There is no = default
modifier to help you. This means writing a lot of swap
member functions, or simply give up on move semantics unless you 1) really need them (non copyable classes) or 2) have profiled your code and need to get rid of copies.
Default copy assignment is generated implicitly, and this is what you get here.