...

/

Initializing string Members from string_view

Initializing string Members from string_view

We'll continue our analysis of the example from the last chapter, this time using std::string_view instead of std::string.

Last time, we were left with this code:

Press + to interact
#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:

Press + to interact
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 Meyers. ...