Search⌘ K
AI Features

Initializing string Members from string_view

Explore the techniques for initializing string members from std::string_view and compare passing std::string by value, reference, or move. Understand the implications of Small String Optimization on performance and learn when passing by value is preferred for safer and simpler code.

Last time, we were left with this code:

C++ 17
#include <iostream>
#include <string>
#include <string_view>
using namespace std;
class UserName
{
std::string mName;
public:
UserName(std::string_view sv) : mName(sv) { }
std::string_view getName(){return mName;}
};
std::string GetString() { return "some string..."; }
int main(){
// creation from a string literal
UserName u1{"John With Very Long Name"};
cout << u1.getName() << endl;
// creation from l-value:
std::string s2 {"Marc With Very Long Name"};
UserName u2 { s2 };
cout << u2.getName() << endl;
// use s2 later...
// from r-value reference
std::string s3 {"Marc With Very Long Name"};
UserName u3 { std::move(s3) };
cout << u3.getName() << endl;
// third case is also similar to taking a return value:
UserName u4 { GetString() };
cout << u4.getName() << endl;
}

Since the introduction of move semantics in C++11, it’s usually better, and safer to pass string as a value and then move from it.

For example:

C++
class UserName {
std::string mName;
public:
UserName(std::string str) : mName(std::move(str)) { }
};

Now we have the following results:

For std::string:

  • u1 - one allocation - for the input argument and then one move into the mName. It’s better than with const std::string& where we got two memory allocations in that case. And similar to the string_view approach.
  • u2 - one allocation - we have to copy the value into the argument, and then we can move from it.
  • u3 - no allocations, only two move operations - that’s better than with string_view and const string&!

When you pass std::string by value not only is the code simpler, there’s also no need to write separate overloads for rvalue references.

See the full code sample:

initializing_from_string_view.cpp

The approach with passing by value is consistent with item 41 - “Consider pass by value for copyable parameters that are cheap to move and always copied” from Effective Modern C++ by Scott ...