Right when I thought I understood what std::move and move constructors do, I tried to write some unit test, actually testing the move constructor for some class...
To my surprise I found, that I cannot think of a way to construct code which actually calls the move constructor. Worse, I cannot even set a breakpoint in the body of the move constructor (in VS2013 community edition, debug, 64bit build).
Wondering if this is a compiler peculiarity, I knocked up some small test code on my freebsd virtual machine, using clang (3.4.1). There, too I fail to find a way to get that move constructor invoked.
#include <iostream> #include <stdint.h> #include <string> #include <algorithm> #include <functional> #include <ctype.h> #include <locale> void InPlaceToUpper( std::string& target ) { std::transform(target.begin(), target.end(), target.begin(), ::toupper); } void InPlaceToLower( std::string& target ) { std::transform(target.begin(), target.end(), target.begin(), ::tolower); } std::string ToUpper( const std::string& s ) { std::string result; result.resize(s.length()); std::transform(s.begin(), s.end(), result.begin(), ::toupper); return result; } std::string ToLower( const std::string& s) { std::string result; result.resize(s.length()); std::transform(s.begin(), s.end(), result.begin(), ::tolower); return result; } class CFoo { std::string m_value; public: CFoo() : m_value() { std::cout << "CFoo() called." << std::endl; } CFoo(const char *value) : m_value(value) { std::cout << "CFoo(const char *) called." << std::endl; } CFoo(const std::string& value ) : m_value(value) { std::cout << "CFoo(const std::string&) called." << std::endl; } CFoo(const CFoo& other ) : m_value(other.m_value) { std::cout << "CFoo() copy constructor called." << std::endl; } CFoo(CFoo&& other ) : m_value(std::move(other.m_value)) { std::cout << "CFoo() move constructor called." << std::endl; std::cout << "other.m_value = " << other.m_value.c_str() << std::endl; } ~CFoo() { std::cout << "~CFoo() called." << std::endl; } const CFoo& operator=( const CFoo& other ) { std::cout << "CFoo copy assignment operator called." << std::endl; if( &other != this ) { m_value = other.m_value; } return *this; } const CFoo& operator=( CFoo&& other ) { std::cout << "CFoo move assignment operator called." << std::endl; if( &other != this ) { m_value = std::move(other.m_value); } return *this; } CFoo ToUpper() { return CFoo(::ToUpper(m_value)); } CFoo ToLower() { return CFoo(::ToLower(m_value)); } const char * ToString() const { return m_value.c_str(); } }; int main( int argc, const char *argv[] ) { { CFoo foo; CFoo foo1("Hello World"); CFoo foo2 = CFoo("Hello again World!"); CFoo foo3(CFoo("Bye world")); CFoo foo4 = CFoo("Bye again world"); CFoo foo5 = foo4.ToUpper(); CFoo foo6 = foo4.ToLower(); foo6 = foo4.ToUpper(); std::cout << "foo4: " << foo4.ToString() << std::endl; foo6 = CFoo("Well well well"); } return 0; } My apologies if the code is not as short as it might possibly be. But there are only a few spots to look at, namely my efforts to get the move constructor invoked in main() and the definition of the various constructors in class Foo.
I am aware of compiler settings which allow turning off RVO and stuff but for the purpose of using the feature "move constructor" in performance aware code, there should be a classic example of when it gets invoked. If that is not the case, I will probably decide not to even bother using move constructors at all.
To answer the question, you can tell me a line I can write in main() which gets the move constructor of CFoo called. Or you can tell me what I am doing wrong.
Does std::string support being moved like that? Maybe this is why my efforts fail?
Thanks, in advance.
CFoo&&instead ofconst CFoo&&?const CFoo&&