将用户定义的文字用于字符串而不是字符串文字的优点

Rak*_*111 54 c++ string user-defined-literals c++14

SO文档中的字符串主题用于说明,在备注部分:

由于C++ 14,而是采用"foo",则建议使用"foo"s,因为s是一个字符串,其将const char * "foo"std::string "foo".

我看到的唯一优势

std::string str = "foo"s;
Run Code Online (Sandbox Code Playgroud)

代替

std::string str = "foo";
Run Code Online (Sandbox Code Playgroud)

在第一种情况下,编译器可以执行copy-elision(我认为),这比第二种情况下的构造函数调用要快.

尽管如此,这是(尚未)保证,因此第一个也可能会调用构造函数,即复制构造函数.

忽略需要使用std::string文字的情况

std::string str = "Hello "s + "World!"s;
Run Code Online (Sandbox Code Playgroud)

使用std::string文字而不是const char[]文字是否有任何好处?

Nic*_*las 50

如果你是"几乎总是自动"人群的一部分,那么UDL就非常重要.它可以让你这样做:

auto str = "Foo"s;
Run Code Online (Sandbox Code Playgroud)

因此,str将是一个真正的std::string,而不是一个const char*.因此,它允许您决定何时做.

这对于自动返回类型扣除也很重要:

[]() {return "Foo"s;}
Run Code Online (Sandbox Code Playgroud)

或任何形式的类型演绎,真的:

template<typename T>
void foo(T &&t) {...}

foo("Foo"s);
Run Code Online (Sandbox Code Playgroud)

我看到使用[...]而不是[...]的唯一优势是,在第一种情况下,编译器可以执行copy-elision(我认为),这比第二种情况下的构造函数调用更快.

Copy-elision并不比构造函数调用快.无论哪种方式,您都在调用对象的构造函数之一.问题是哪一个:

std::string str = "foo";
Run Code Online (Sandbox Code Playgroud)

这将挑起来的构造函数的调用std::string,这需要const char*.但由于std::string必须将字符串复制到自己的存储中,因此必须获取字符串的长度.并且因为它不知道长度,所以这个构造函数被strlen用来获取它(从技术上来说char_traits<char>::length,但这可能不会更快).

相比之下:

std::string str = "foo"s;
Run Code Online (Sandbox Code Playgroud)

这将使用具有此原型的UDL模板:

string operator "" s(const char* str, size_t len);
Run Code Online (Sandbox Code Playgroud)

请参阅,编译器知道字符串文字的长度.因此,UDL代码传递一个指向字符串和大小的指针.因此,它可以调用std::string带a const char* a 的构造函数size_t.所以不需要计算字符串的长度.

有问题的建议并不适合您转换并将文字的每次使用转换为s版本.如果您对chars 数组的限制很好,请使用它.建议是,如果你要将这个字面存储在a中std::string,最好完成它,而它仍然是文字而不是模糊不清const char*.

  • 1)没有UDL,它是一个指针,而不是一个数组.`auto`衰变.2)(超迂腐):它调用`char_traits <char> :: length`,这可能但不需要调用`strlen`. (3认同)
  • 模板函数类型推导也可能是一个很好的例子. (2认同)
  • @ Cheersandhth.-Alf:如果您想要的是std :: string而不是数组,那么执行auto str =“ Foo”;是有问题的。 (2认同)

Che*_*Alf 19

使用建议"blah"s与效率无关,而与新手代码的正确性无关.

没有C背景的C++新手倾向于认为"blah"导致某个合理字符串类型的对象.例如,这样人们就可以编写像"blah" + 42许多脚本语言一样的东西.与"blah" + 42在C++中,然而,一个刚刚即被未定义行为,寻址超出字符数组的末尾.

但是,如果将该字符串文字写入,"blah"s则会产生编译错误,这是更可取的.


Jar*_*d42 13

此外,UDL使\0字符串更容易

std::string s = "foo\0bar"s; // s contains a \0 in its middle.
std::string s2 = "foo\0bar"; // equivalent to "foo"s
Run Code Online (Sandbox Code Playgroud)