本文介绍了对字符串使用用户定义的文字而不是字符串文字的优点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

SO文档中的字符串主题在备注部分曾经说过:

我看到的唯一优势

  std :: string str = foo s; 

而不是

  std :: string str = foo; 

在第一种情况下,编译器可以执行复制删除(我认为),这是



尽管如此,这(尚未)得到保证,所以第一个也可以调用构造函数,即复制构造函数。 / p>

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

  std :: string str = Hello s + World! s; 

使用 std :: string 文字而不是 const char [] 文字?

解决方案

如果如果您是几乎总是自动人群的一部分,那么UDL非常重要。它可以让您执行以下操作:

  auto str = Foo s; 

因此, str 才是真正的 std :: string ,而不是 const char * 。因此,它使您可以决定何时进行操作。



这对于自动返回类型推导也很重要:

  [](){返回 Foo s;} 

或任何形式的类型推导,实际上是:

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

foo( Foo s);



复制删除不比构造函数调用快。无论哪种方式,您都在调用对象的构造函数之一。问题是哪个

  std :: string str = foo; 

这将引起对 std :: string 的构造函数的调用code>,其中包含 const char * 。但是由于 std :: string 必须将字符串复制到其自己的存储中,因此必须获取字符串的长度。而且由于不知道长度,因此该构造方法被迫使用 strlen 来获取长度(从技术上讲, char_traits< char> :: length ,但这可能不会快得多)。



对比:

  std :: string str = foo s; 

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

 字符串运算符 s(const char * str,size_t len); 

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



有问题的建议不是让您遍历转换使用文字放入 s 版本。如果您满意 char s数组的限制,请使用它。忠告是,如果要将该文字存储在 std :: string 中,则最好在仍是文字而不是模糊的 const char *


The strings topic in the SO Documentation used to say, in the Remarks section:

The only advantage I see using

std::string str = "foo"s;

instead of

std::string str = "foo";

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.

Nonetheless, this is (not yet) guaranteed, so the first one might also call a constructor, the copy constructor.

Ignoring cases where it is required to use std::string literals like

std::string str = "Hello "s + "World!"s;

is there any benefit of using std::string literals instead of const char[] literals?

解决方案

If you're part of the "Almost Always Auto" crowd, then the UDL is very important. It lets you do this:

auto str = "Foo"s;

And thus, str will be a genuine std::string, not a const char*. It therefore permits you to decide when to do which.

This is also important for auto return type deduction:

[]() {return "Foo"s;}

Or any form of type deduction, really:

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

foo("Foo"s);

Copy-elision is not faster than the constructor call. Either way, you're calling one of the object's constructors. The question is which one:

std::string str = "foo";

This will provoke a call to the constructor of std::string which takes a const char*. But since std::string has to copy the string into its own storage, it must get the length of the string to do so. And since it doesn't know the length, this constructor is forced to use strlen to get it (technically, char_traits<char>::length, but that's probably not going to be much faster).

By contrast:

std::string str = "foo"s;

This will use the UDL template that has this prototype:

string operator "" s(const char* str, size_t len);

See, the compiler knows the length of a string literal. So the UDL code is passed a pointer to the string and a size. And thus, it can call the std::string constructor that takes a const char* and a size_t. So there's no need for computing the string's length.

The advice in question is not for you to go around and convert every use of a literal into the s version. If you're fine with the limitations of an array of chars, use it. The advice is that, if you're going to store that literal in a std::string, it's best to get that done while it's still a literal and not a nebulous const char*.

这篇关于对字符串使用用户定义的文字而不是字符串文字的优点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-02 04:13