Std :: string & vs boost :: string_ref

Does it matter if I use boost::string_refover std::string&? I mean, is it really more efficient to use boost::string_refthe std version when processing strings? I really don't understand the explanations offered here: http://www.boost.org/doc/libs/1_61_0/libs/utility/doc/html/string_ref.html . What really bothers me is that it is std::stringalso a descriptor class that only points to allocated memory, and since C ++ 11, with the semantics of movement, the copy operations noted in the article above will not happen. So which one is more effective?

+5
source share
5 answers

I never used this, it seems to me that its purpose is to provide an interface similar to std::string, but without having to select a line for manipulation. Take the following example extract_part(): it is given a hard-coded array of C "ABCDEFG", but since the original function accepts std::string, it is allocated (it std::stringwill have its own version "ABCDEFG"). Using string_ref, distribution does not occur, it uses a reference to the initial one "ABCDEFG". The limitation is that the string is read-only.

+4
source

A use case string_ref(or string_viewin recent Boost and C ++ 17) is for substring references .

Case when

  • the source line is std::string

(a-) , std::string const&.

, string_ref (, sref.substring(...)) string_ref std::string.

+5

string_view , string_ref.

, , std::string ,

A string , . A string_view - , . - , string_view.

, , char, , string, . A string_view , char. ; string_view const, , .

++ 11, , , , .

, . - .

string ( ), string s. ++ 98 RVO , . string_view, string s. .

extract_part("ABCDEFG") a string_view, char, . string char.

bar.substr(2,3) a string_view, , string_view. string .

, ?

, , . , , .

string_view , , , .

+2

std::string, , boost::string_ref const char*. , foo std::string?

void foo(const std::string&);

foo("won't work"); // no support for `const char*`

boost::string_ref const char*, , const char*, std::string.

N3442 .

+1

: std::string_view over const std::string& , const char* std::string . , , ( ) .

() (, , s.at(2)):

char getThird(std::string s)
{
    if (s.size() < 3) throw std::runtime_error("String too short");
    return s[2];
}

, . , , , () . . const:

char getThird(const std::string& s);

, std::string getThird. : , const char* ? , std::string, .

:

char getThird(const char* s)
{
    if (std::strlen(s) < 3) throw std::runtime_error("String too short");
    return s[2];
}

, const char*. std::string , getThird(myStr.c_str()): getThird(myStr.c_str()). , std::string , getThird , . - , checkStringForBadHacks !

, std::string . , , , ? std::strlen, , . , , , , .

std::string_view ( boost::string_view, boost::string_ref):

char getThird(std::string_view s)
{
    if (s.size() < 3) throw std::runtime_error("String too short");
    return s[2];
}

, , .size(), , , :

  • std::string, std::string_view.
  • const char* , std::string_view.
    • , , std::string_view , , , , ( ). , const char* ( ), std::string_view std::string_view . , , , .
  • , , . , . std::string_view .

, , , std::string , , std::string_view. , , , - . :

std::string changeThird(std::string s, char c)
{
    if (s.size() < 3) throw std::runtime_error("String too short");
    s[2] = c;
    return s;
}

// vs.

std::string changeThird(std::string_view s, char c)
{
    if (s.size() < 3) throw std::runtime_error("String too short");
    std::string result = s;
    result[2] = c;
    return result;
}

, : , s , ( , std::string. , result. return , ( std::move(result)) , , .

The reason the first version might be better is because it can actually make null copies if the caller moves the argument:

std::string something = getMyString();
std::string other = changeThird(std::move(something), "x");

In this case, the first changeThirddoes not contain any copy at all, and the second -.

0
source

Source: https://habr.com/ru/post/1653261/


All Articles