Jump to content
  • Advertisement
Sign in to follow this  
matt77hias

std::string_view

Recommended Posts

Can string_views be used in combination with setters?

I would like to have something like the code below. Unfortunately, my constructors are ambiguous for the second invocation. The view is capable of reducing the number of methods, std::string, C string, but could it be used as well in combination with move semantics? Or is the view solely intended for "you may look at the string, but you are not allowed to own it."?

#include <iostream>

#include <string>
#include <string_view>
using namespace std;

struct Str {
    
    explicit Str(string_view str)
        : m_str(str) {}
    explicit Str(string &&str)
        : m_str(std::move(str)) {} 
    
    string m_str;
};

int main() {
    string a = "a";
    
    Str as = Str(a);
    Str bs = Str("b");
}

 

Edited by matt77hias

Share this post


Link to post
Share on other sites
Advertisement

string_views never own. The ambiguity comes form the fact that you are creating a temporary object out of your string-literal. The compiler cannot figure out which of the two possibilities you want, either a string_view which will then be used to construct a new std::string in your constructor, or create a temporary string object and then move-construct your member from that.

I don't see a good reason to use string_view here, you'll have to make a copy sooner or later anyway, why not create it at the call site and forgot about all the difficulties you are facing now?

Share this post


Link to post
Share on other sites
1 hour ago, rnlf_in_space said:

I don't see a good reason to use string_view here, you'll have to make a copy sooner or later anyway, why not create it at the call site and forgot about all the difficulties you are facing now?

But then I will have again three constructors:

explicit Str(const string &str)

explicit Str(string &&str)

explicit Str(const char *str)

Note that I could remove the last one. Makes me actually wondering whether the last one is actually needed (i.e. can result in some performance advantage when using C strings directly)? The C string will result in the implicit creation of a temporary string which will be passed as an rvalue reference, right?

Edited by matt77hias

Share this post


Link to post
Share on other sites

Yeah, this can all lead to an explosion of overloads very quickly. I think passing an std::string by value and then moving from that string to initialize your members has the best performance/effort ratio.
This talk by Nicolai Josuttis illustrates the problem very nicely, even if for slightly more complex cases:

In your case I'd probably just go with Str(std::string str) : m_str(std::move(str)) {}, that way you create one copy of your string at the call site and then just use the (comparatively) cheap move constructor to initialize your member.

std::string only has an explicit constructor that takes a string_view though, so if you'll either have to create the string object at the call site, too, or overload with something like

Std(std::string_view v) : Str(std::string(v)) {}.

I'd prefer the first option (making the copy explicit at the call site) because it doesn't hide the extra allocations and memcpy.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!