Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Advantages of using user-defined literal for strings instead of string literal

The strings topic in the SO Documentation used to say, in the Remarks section:

Since C++14, instead of using "foo", it is recommended to use "foo"s, as s is a string literal, which converts the const char * "foo" to std::string "foo".

The only advantage I see using

std::string str = "foo"s; 

instead of

std::string str = "foo"; 

is that in the first case the compiler can perform copy-elision (I think), which would be faster than the constructor call in the second case.

Nonetheless, this is (not yet) guaranteed, so the first one might also call a constructor, the copy constructor.

Ignoring cases where it is required to use std::string literals like

std::string str = "Hello "s + "World!"s; 

is there any benefit of using std::string literals instead of const char[] literals?

like image 280
Rakete1111 Avatar asked Jul 28 '16 02:07

Rakete1111


People also ask

What is the difference between string and string literal?

Definition. String literal in Java is a set of characters that is created by enclosing them inside a pair of double quotes. In contrast, String Object is a Java is a set of characters that is created using the new() operator. Thus, this explains the main difference between string literal and string object.

What is a user defined literal?

In source code, any literal, whether user-defined or not, is essentially a sequence of alphanumeric characters, such as 101 , or 54.7 , or "hello" or true . The compiler interprets the sequence as an integer, float, const char* string, and so on.

What is the difference between a string and string literal in a Python program?

A string literal is what you type into your source code. The string value is what gets output when you print it.

What is the difference between string and string literal in c?

C-strings are simply implemented as a char array which is terminated by a null character (aka 0 ). This last part of the definition is important: all C-strings are char arrays, but not all char arrays are c-strings. C-strings of this form are called “string literals“: const char * str = "This is a string literal.


2 Answers

If you're part of the "Almost Always Auto" crowd, then the UDL is very important. It lets you do this:

auto str = "Foo"s; 

And thus, str will be a genuine std::string, not a const char*. It therefore permits you to decide when to do which.

This is also important for auto return type deduction:

[]() {return "Foo"s;} 

Or any form of type deduction, really:

template<typename T> void foo(T &&t) {...}  foo("Foo"s); 

The only advantage I see using [...] instead of [...] is that in the first case the compiler can perform copy-elision (I think), which would be faster than the constructor call in the second case.

Copy-elision is not faster than the constructor call. Either way, you're calling one of the object's constructors. The question is which one:

std::string str = "foo"; 

This will provoke a call to the constructor of std::string which takes a const char*. But since std::string has to copy the string into its own storage, it must get the length of the string to do so. And since it doesn't know the length, this constructor is forced to use strlen to get it (technically, char_traits<char>::length, but that's probably not going to be much faster).

By contrast:

std::string str = "foo"s; 

This will use the UDL template that has this prototype:

string operator "" s(const char* str, size_t len); 

See, the compiler knows the length of a string literal. So the UDL code is passed a pointer to the string and a size. And thus, it can call the std::string constructor that takes a const char* and a size_t. So there's no need for computing the string's length.

The advice in question is not for you to go around and convert every use of a literal into the s version. If you're fine with the limitations of an array of chars, use it. The advice is that, if you're going to store that literal in a std::string, it's best to get that done while it's still a literal and not a nebulous const char*.

like image 59
Nicol Bolas Avatar answered Sep 23 '22 05:09

Nicol Bolas


The advice to use "blah"s has nothing to do with efficiency and all to do with correctness for novice code.

C++ novices who don't have a background in C, tend to assume that "blah" results in an object of some reasonable string type. For example, so that one can write things like "blah" + 42, which works in many script languages. With "blah" + 42 in C++, however, one just incurs Undefined Behavior, addressing beyond the end of the character array.

But if that string literal is written as "blah"s then one instead gets a compilation error, which is much preferable.

like image 43
Cheers and hth. - Alf Avatar answered Sep 23 '22 05:09

Cheers and hth. - Alf