使用用戶定義的字符串文字而不是字符串文字的優點

[英]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:

SO文檔中的字符串主題通常在備注部分中說:

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".

由於c++ 14,不使用“foo”,建議使用“foo”s,因為s是字符串文字,它將const char * foo”轉換為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.

在第一種情況下,編譯器可以執行copy-elision(我認為),這比在第二種情況下的構造函數調用要快。

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

盡管如此,這是(還沒有)保證的,所以第一個可能會調用構造函數,即copy構造函數。

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

忽略需要使用std::string literals如的情況

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

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

使用std::string literals而不是const char[] literals有什么好處嗎?

4 个解决方案

#1


44  

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

如果你是“幾乎總是自動”人群的一部分,那么UDL是非常重要的。它讓你這樣做:

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.

因此,str將是一個真正的std::string,而不是const char*。因此它允許你決定什么時候做什么。

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).

這將引發對std::string構造函數的調用,該構造函數使用const char*。但是由於std::string必須將字符串復制到它自己的存儲中,所以它必須獲得字符串的長度。由於它不知道長度,所以這個構造函數不得不使用strlen來獲取它(嚴格地說,char_traits : length,但是可能不會快很多)。

By contrast:

相比之下:

std::string str = "foo"s;

This will use the UDL template that has this prototype:

這將使用有此原型的UDL模板:

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.

看,編譯器知道字符串文字的長度。因此,udf代碼被傳遞一個指向字符串和大小的指針。因此,它可以調用std: string構造函數,它接受const char*和size_t。所以不需要計算弦的長度。

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*.

問題的建議不是讓你到處去,把一個文字的每一個用法轉換成s版本。如果您對chars數組的限制沒有問題,請使用它。建議是,如果要將該文字存儲在std::string中,最好在它仍然是一個文字而不是一個模糊的const char*時完成它。

#2


17  

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

使用“blah”的建議與效率無關,而是與新手代碼的正確性有關。

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.

沒有C語言背景的c++新手,傾向於認為“blah”會導致某種合理的字符串類型。例如,一個人可以寫“blah”+ 42,這在很多腳本語言中都是有效的。然而,在c++中使用“blah”+ 42,只會導致未定義的行為,在字符數組的末尾尋址。

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

但是,如果字符串文字被寫成“blah”,那么就會出現編譯錯誤,這是更可取的。

#3


10  

In addition, UDL makes it easier to have \0 in the string

此外,UDL使字符串中有\0變得更容易

std::string s = "foo\0bar"s; // s contains a \0 in its middle.
std::string s2 = "foo\0bar"; // equivalent to "foo"s

#4


2  

  1. Using a C++ string literal means we do not need to call strlen to compute the length. The compiler already knows it.
  2. 使用c++字符串字面量意味着我們不需要調用strlen來計算長度。編譯器已經知道了。
  3. Might allow library implemetations where the string data points to memory in global space will using C literals must always force a copy of the data to heap memory on construction.
  4. 可能允許庫實現,其中字符串數據指向全局空間中的內存,使用C文字必須始終強制數據的副本在構造時堆內存。

注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:https://www.itdaan.com/blog/2016/07/28/71222ed4ae01c35694e81f0116f7b05c.html



 
粤ICP备14056181号  © 2014-2021 ITdaan.com