Is it a good idea to assign a std::string_view type in constructor?

446 Views Asked by At

I understand that using std::string_view is better than std::string because it allows const char* and std::string values to be passed without needing a std::string object to be created. Also i understand the it provides a ReadOnly access

However, i was wondering if it is a good practice to define a public std:string_view variable and update it through the class constructor.

i.e: What is the difference between test1 and test2, assuming test1 or test2 is defined in a library class which can be instantiated by different clients.

class test1{
public:
 std::string_view name_;
 
 test1 (std::string_view name): name_ {name} {};
 void print() {
     cout<<"test1 "<<name_<<endl;
 }
};

class test2{
public:
 std::string name_;
 
 test2 (std::string_view name): name_ {name} {};
 void print() {
     cout<<"test2 "<<name_<<endl;
 }

};
2

There are 2 best solutions below

4
eerorika On

While it's not wrong as such, it's potentially unsafe. It's extremely important for the user of the class to understand that the member will remain valid only as long as the pointed string's lifetime, which may be shorter than that of the object. It should be both documented clearly, and the name of the class should reflect its referential nature. Some examples are suffixes such as _view or _ref.

The class test1 won't be useful in such cases where the lifetime must be longer than that of the pointed string. This consideration is same as when using a member of type const char*.

0
marcinj On

There are important differences.

  1. Lifetime of the underlying data is different:

     Test1 createTest1() {
        std::string tempName = "temporary";
        return Test1(tempName);
     }
     // here name_ will become a dangling reference, this is UB
     test1 a = createTest1();
    

    No such problem will happen in case of test2.

  2. std::string will allocate data which is greater overhead over a version with string_view.

  3. You cannot modify string_view, its immutable (but it might change in c++23)

  4. Version with std::string requires more memory that the version with std::string_view. std::string even when in SSO mode requires, some array of bytes to store small strings, and this array is usually a minimal size of std::string.

  5. The choice of test1 vs test2 can greatly depend on how your application is structured, if you mostly pass string_view-s then use test1, otherwise if you use std::string then use test2.

  6. std::string supports more operations than std::string_view.