SO文档中的字符串主题在备注部分中曾经说过:
从C++14开始,建议使用"foo"s
而不是"foo"
,因为s
是一个字符串,它将const char *
"foo"
转换为std::string
"foo"
。
我认为唯一的优势就是
std::string str = "foo"s;
代替
std::string str = "foo";
在第一种情况下,编译器可以执行复制省略(我认为),这将比第二种情况下的构造函数调用更快。
尽管如此,这是(尚未)有保证的,所以第一个函数也可能调用一个构造函数,即复制构造函数。
忽略 * 必须 * 使用std::string
文本的情况,如
std::string str = "Hello "s + "World!"s;
使用std::string
literals而不是const char[]
文本有什么好处吗?
4条答案
按热度按时间23c0lvtd1#
如果你是“几乎总是自动”人群中的一员,那么UDL就非常重要,它可以让你做到:
因此,
str
将是一个真正的std::string
,而不是const char*
,因此它允许您决定何时执行哪个操作。这对于自动返回类型推导也很重要:
或者任何形式的类型推导,真的:
我认为使用[...]而不是[...]的唯一优点是,在第一种情况下,编译器可以执行复制省略(我认为),这将比第二种情况下的构造函数调用更快。
复制省略并不比构造函数调用快,无论哪种方式,你都是在调用对象的构造函数之一,问题是 * 哪一个 *:
这将触发对
std::string
的构造函数的调用,该构造函数接受const char*
,但是由于std::string
必须将字符串复制到它自己的存储器中,因此它必须获得字符串的长度,并且由于它不知道长度,因此该构造函数被迫使用strlen
来获得它(技术上是char_traits<char>::length
,但可能不会快很多)。相比之下:
这将使用具有以下原型的UDL模板:
看,* 编译器 * 知道字符串的长度,所以UDL代码被传递了一个指向字符串的指针和一个大小,这样,它就可以调用
std::string
构造函数,这个构造函数接受const char*
* 和size_t
*,所以不需要计算字符串的长度。这里的建议并不是让你把每次使用的字面量都转换成
s
版本,如果你不介意char
数组的限制,就使用它,建议是,如果你要把字面量存储在std::string
中,最好在它还是字面量而不是模糊的const char*
时完成。kpbwa7wx2#
使用
"blah"s
的建议与效率无关,而与新手代码的正确性有关。没有C语言背景的C初学者,倾向于假设
"blah"
会导致一个合理的字符串类型的对象。例如,这样就可以写"blah" + 42
这样的东西,它可以在许多脚本语言中工作。然而,在C中使用"blah" + 42
,只会导致未定义的行为,寻址字符数组的末尾。但是如果字符串文字被写成
"blah"s
,那么就会得到一个编译错误,这是更可取的。0s0u357o3#
此外,UDL使字符串中包含
\0
变得更加容易r8xiu3jd4#
1.使用C++字符串意味着我们不需要调用
strlen
来计算长度,因为编译器已经知道了。1.可能允许库实现,其中字符串数据指向全局空间中的内存,将使用C文本,必须始终在构造时强制将数据副本复制到堆内存。