Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Efficient string constructor

Tags:

c++

string

Some classes I meet, have a dual string constructor:

 construct( const std::string& s );
 construct( const char* s );

Having a std::string constructor has the obvious benefit of being able to pass a std::string without c_str(). However, if the argument is stored in a std::string anyway, is there any benefit of having the const char* constructor?

In particular:

 construct( const std::string& s ) : m_string( s ) {}
 construct( const char* s ) : m_string( s ) {}
 std::string m_string;

Will the second constructor be faster for string literals and char* variables, or will it be optimized away?

Additional question - does C++11 move construction change anything here?

like image 911
Kornel Kisielewicz Avatar asked Jul 30 '13 00:07

Kornel Kisielewicz


2 Answers

In C++03, or in C++11 without specifying move semantics, the const char * to std::string implicit conversion creates a temporary string, which then gets copied to the member. This implements an extra copy.

In C++11 you can have the temporary moved instead after passing by value:

construct( std::string s ) : member( std::move( s ) ) {}

The only other thing I can think of is compatibility with other classes providing conversion operators.

struct String {
    operator char const * () const;
};

Since only one user-defined conversion may apply implicitly, the std::string function won't receive a String argument by conversion through char const *. Note, however, that with an additional conversion function to std::string and both constructors, the result would be overload ambiguity.

like image 192
Potatoswatter Avatar answered Oct 06 '22 16:10

Potatoswatter


If you have just char* and only first constructor, copy may be made 2 times. in std::string(char*) and in construct(std::string)

While in second constructor pointer will be copied(it's fast) and then string copied.

In C++11 good idea is to create 1 constructor

 construct(std::string s ) : m_string( std::move(s) ) {}

In this case if you have just char* data may be copied in string ctor, but string will be temporary, so it will be just moved in construct ctor

This code prints "creating, copy"
This code prints "creating, move"

like image 28
RiaD Avatar answered Oct 06 '22 15:10

RiaD