对字符串使用用户定义的文字而不是字符串文字的优点
Advantages of using user-defined literal for strings instead of string literal
SO Documentation中的strings主题曾经说过,在Remarks部分:
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"
.
我看到使用
的唯一优势
std::string str = "foo"s;
而不是
std::string str = "foo";
在第一种情况下,编译器可以执行复制省略(我认为),这将比第二种情况下的构造函数调用更快。
尽管如此,这(尚未)得到保证,因此第一个也可能调用构造函数,即复制构造函数。
忽略需要使用std::string
文字的情况,例如
std::string str = "Hello "s + "World!"s;
使用 std::string
文字而不是 const char[]
文字有什么好处吗?
如果您是 "Almost Always Auto" 人群中的一员,那么 UDL 非常重要。它可以让你这样做:
auto str = "Foo"s;
因此,str
将是真正的 std::string
,而不是 const char*
。因此,它允许您决定何时做什么。
这对自动return类型推导也很重要:
[]() {return "Foo"s;}
或任何形式的类型推导,真的:
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.
复制省略并不比构造函数调用快。无论哪种方式,您都在调用对象的构造函数之一。问题是哪一个:
std::string str = "foo";
这将引发对 std::string
的构造函数的调用,该构造函数采用 const char*
。但是由于 std::string
必须将字符串复制到它自己的存储中,因此它必须获得字符串的长度才能这样做。由于它不知道长度,因此该构造函数被迫使用 strlen
来获取它(从技术上讲,char_traits<char>::length
,但这可能不会更快)。
对比:
std::string str = "foo"s;
这将使用具有此原型的 UDL 模板:
string operator "" s(const char* str, size_t len);
看,编译器 知道字符串文字的长度。因此 UDL 代码被传递了一个指向字符串的指针和一个大小。因此,它可以调用带有 const char*
和 的 std::string
构造函数和 size_t
。所以不需要计算字符串的长度。
有问题的建议不是让您四处走动并将每个 文字使用转换为s
版本。如果您不介意 char
数组的限制,请使用它。建议是,如果您要将该文字存储在 std::string
中,最好在它仍然是文字而不是模糊的 const char*
.
时完成它。
- 使用 C++ 字符串文字意味着我们不需要调用
strlen
来计算长度。编译器已经知道了。
- 可能允许库实现,其中字符串数据指向全局内存space将使用 C 文字,必须始终强制数据副本在构造时堆内存。
使用"blah"s
的建议与效率无关,与新手代码的正确性有关。
没有 C 语言背景的 C++ 新手倾向于假设 "blah"
会产生某种合理字符串类型的对象。例如,这样就可以编写 "blah" + 42
之类的东西,它适用于许多脚本语言。然而,在 C++ 中使用 "blah" + 42
,只会导致未定义的行为,寻址超出字符数组的末尾。
但是如果该字符串文字被写成 "blah"s
那么一个人反而会得到一个编译错误,这是更可取的。
此外,UDL 使得在字符串
中包含 [=11=]
更容易
std::string s = "foo[=10=]bar"s; // s contains a [=10=] in its middle.
std::string s2 = "foo[=10=]bar"; // equivalent to "foo"s
SO Documentation中的strings主题曾经说过,在Remarks部分:
Since C++14, instead of using
"foo"
, it is recommended to use"foo"s
, ass
is a string literal, which converts theconst char *
"foo"
tostd::string
"foo"
.
我看到使用
的唯一优势std::string str = "foo"s;
而不是
std::string str = "foo";
在第一种情况下,编译器可以执行复制省略(我认为),这将比第二种情况下的构造函数调用更快。
尽管如此,这(尚未)得到保证,因此第一个也可能调用构造函数,即复制构造函数。
忽略需要使用std::string
文字的情况,例如
std::string str = "Hello "s + "World!"s;
使用 std::string
文字而不是 const char[]
文字有什么好处吗?
如果您是 "Almost Always Auto" 人群中的一员,那么 UDL 非常重要。它可以让你这样做:
auto str = "Foo"s;
因此,str
将是真正的 std::string
,而不是 const char*
。因此,它允许您决定何时做什么。
这对自动return类型推导也很重要:
[]() {return "Foo"s;}
或任何形式的类型推导,真的:
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.
复制省略并不比构造函数调用快。无论哪种方式,您都在调用对象的构造函数之一。问题是哪一个:
std::string str = "foo";
这将引发对 std::string
的构造函数的调用,该构造函数采用 const char*
。但是由于 std::string
必须将字符串复制到它自己的存储中,因此它必须获得字符串的长度才能这样做。由于它不知道长度,因此该构造函数被迫使用 strlen
来获取它(从技术上讲,char_traits<char>::length
,但这可能不会更快)。
对比:
std::string str = "foo"s;
这将使用具有此原型的 UDL 模板:
string operator "" s(const char* str, size_t len);
看,编译器 知道字符串文字的长度。因此 UDL 代码被传递了一个指向字符串的指针和一个大小。因此,它可以调用带有 const char*
和 的 std::string
构造函数和 size_t
。所以不需要计算字符串的长度。
有问题的建议不是让您四处走动并将每个 文字使用转换为s
版本。如果您不介意 char
数组的限制,请使用它。建议是,如果您要将该文字存储在 std::string
中,最好在它仍然是文字而不是模糊的 const char*
.
- 使用 C++ 字符串文字意味着我们不需要调用
strlen
来计算长度。编译器已经知道了。 - 可能允许库实现,其中字符串数据指向全局内存space将使用 C 文字,必须始终强制数据副本在构造时堆内存。
使用"blah"s
的建议与效率无关,与新手代码的正确性有关。
没有 C 语言背景的 C++ 新手倾向于假设 "blah"
会产生某种合理字符串类型的对象。例如,这样就可以编写 "blah" + 42
之类的东西,它适用于许多脚本语言。然而,在 C++ 中使用 "blah" + 42
,只会导致未定义的行为,寻址超出字符数组的末尾。
但是如果该字符串文字被写成 "blah"s
那么一个人反而会得到一个编译错误,这是更可取的。
此外,UDL 使得在字符串
中包含[=11=]
更容易
std::string s = "foo[=10=]bar"s; // s contains a [=10=] in its middle.
std::string s2 = "foo[=10=]bar"; // equivalent to "foo"s