Should methods returning const std::string& return const std::string_view instead?

前端 未结 1 1024
谎友^
谎友^ 2021-02-19 05:51

Assume we have a simple getter method in a class that returns a const reference to a std::string member:

const std::string& getStri         


        
1条回答
  •  余生分开走
    2021-02-19 06:10

    Yes, you should write:

    const std::string& getString() const noexcept { return someString; }
    

    Instead of (note: not const, because never return const values):

    std::string_view getString() const noexcept { return someString; }
    

    The reason is - you already have a string. So it's not like you have to pay anything extra to get a string out of it. And string has one notable semantic difference to an arbitrary string_view: it's null-terminated by guarantee. We know this. Maybe some downstream user needs to rely on that information. If they need null-termination (e.g. they need to pass to some C API that requires it) and you give a string_view, they have to make a string out of it themselves. You save nothing, but potentially make downstream users do more work.

    If, however, you had a vector instead... then I would suggest to return a span or the equivalent thereof. Since there is no semantic difference and you're just providing a view.


    There also the separate argument of what:

    auto x = obj.getString();
    

    should do. This either takes a copy of the string (expensive, but safe) or effectively a reference to it (cheap, but potentially dangling). But it doesn't entirely look like a reference, it looks like a value. This is a broad issue with reference-semantic types in general (things like reference_wrapper, string_view, span, tuple, optional if it existed, etc.).

    I don't have an answer for this case, but it's something to be aware of.

    0 讨论(0)
提交回复
热议问题