如果您是“几乎总是自动”人群中的一员,那么 UDL 就非常重要。它可以让你这样做:
auto str = "Foo"s;
因此,str
将是一个真正的std::string
,而不是一个const char*
。因此,它允许您决定何时执行哪个操作。
这对于自动返回类型扣除也很重要:
[]() {return "Foo"s;}
或者任何形式的类型推导,真的:
template<typename T>
void foo(T &&t) {...}
foo("Foo"s);
我看到使用 [...] 而不是 [...] 的唯一优点是,在第一种情况下,编译器可以执行复制省略(我认为),这比第二种情况下的构造函数调用要快。
复制省略并不比构造函数调用快。无论哪种方式,您都在调用对象的构造函数之一。问题是哪一个:
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 代码被传递了一个指向字符串的指针和一个大小。因此,它可以调用带有 a和a的std::string
构造函数。所以不需要计算字符串的长度。const char*
size_t
有问题的建议不是让您四处走动并将文字的每次使用都转换为s
版本。如果您对 s 数组的限制感到满意char
,请使用它。建议是,如果您要将文字存储在 astd::string
中,最好在它仍然是文字而不是模糊的时候完成const char*
。