There was a post on the ISOCpp blog last week about passing by const-reference or by value. The full StackOverflow post is Why do we copy then move? and another related post asks Are the days of passing by const ref over?.
First, as my friend and colleague Andy Sawyer pointed out in a conversation, taking a parameter by value leaks implementation detail out of the function so he recommends passing by const reference unless there’s a good reason not to.
Second, whilst passing by value presents the opportunity for the callee to store data using move semantics, the callee has to invoke that explicitly by calling std::move:
#include <string> #include <iostream> class A { public: A( const std::string& s ) : str_( s ) { std::cout << "A: s='" << s << "', str_='" << str_ << "'\n"; } private: std::string str_; }; class B { public: B( std::string s ) : str_( s ) { std::cout << "B: s='" << s << "', str_='" << str_ << "'\n"; } private: std::string str_; }; class C { public: C( std::string s ) : str_( std::move(s) ) { std::cout << "C: s='" << s << "', str_='" << str_ << "'\n"; } private: std::string str_; }; int _tmain(int argc, _TCHAR* argv[]) { A a( "ConstReference" ); // Constructor(char*) then CopyConstructor B b( "PassByValue" ); // Constructor(char*) then CopyConstructor C c( "PassByValueAndMove" );// Constructor(char*) then MoveConstructor return 0; }
so basically, still always pass by const& if you do not intend on chaning the object inside the function?
Yeah, const& remains a sensible choice, but pass-by-value wins if the method is always going to copy.