SO文档中的字符串主题用于说明,在备注部分:
从C ++ 14开始,不建议使用
"foo"
,而是使用"foo"s
,因为s
是一个字符串文字,可以转换const char *
{{ 1}}到"foo"
std::string
。
我看到的唯一优势
"foo"
而不是
std::string str = "foo"s;
是第一种情况,编译器可以执行copy-elision(我认为),这比第二种情况下的构造函数调用要快。
尽管如此,这是(尚未)保证,所以第一个也可能会调用构造函数,复制构造函数。
忽略必需使用std::string str = "foo";
文字的情况,例如
std::string
使用std::string str = "Hello "s + "World!"s;
文字而不是std::string
文字是否有任何好处?
答案 0 :(得分:47)
如果你是“几乎总是自动”人群的一部分,那么UDL非常重要。它可以让你这样做:
auto str = "Foo"s;
因此,str
将是真正的std::string
,而不是const char*
。因此,它允许您决定何时做。
这对于自动退货类型扣除也很重要:
[]() {return "Foo"s;}
或任何形式的类型演绎,真的:
template<typename T>
void foo(T &&t) {...}
foo("Foo"s);
我看到使用[...]而不是[...]的唯一优势是,在第一种情况下,编译器可以执行copy-elision(我认为),这将比第二次构造函数调用更快情况下。
Copy-elision并不比构造函数调用快。无论哪种方式,您都在调用对象的构造函数之一。问题是哪一个:
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代码传递一个指向字符串和大小的指针。因此,它可以调用带有std::string
和 a const char*
的{{1}}构造函数。所以不需要计算字符串的长度。
有问题的建议不适合您将每个使用文字转换为size_t
版本。如果您对s
数组的限制很好,请使用它。建议是,如果你要将这个文字存储在char
中,那么最好还是将它完成,而它仍然是文字而不是模糊的std::string
。
答案 1 :(得分:19)
使用"blah"s
的建议与效率无关,而与新手代码的正确性无关。
没有C语言背景的C ++新手倾向于认为"blah"
会产生一些合理字符串类型的对象。例如,这样就可以编写"blah" + 42
之类的东西,它可以在许多脚本语言中运行。但是,在C ++中使用"blah" + 42
,只会产生未定义的行为,在字符数组的末尾进行寻址。
但是如果该字符串文字被写为"blah"s
,那么一个人会得到一个编译错误,这是更可取的。
答案 2 :(得分:12)
此外,UDL使字符串
中的\0
变得更容易
std::string s = "foo\0bar"s; // s contains a \0 in its middle.
std::string s2 = "foo\0bar"; // equivalent to "foo"s
答案 3 :(得分:2)