简体   繁体   English

为什么在分配给 const std::string 时会复制字符串文字?

[英]Why is a string literal copied when assigning to a const std::string?

According to cppreference.com , when a const std::string is constructed from an input const char* (eg const std::string("some literal"); ), a copy of the C string is stored in the std::string .根据cppreference.com ,当从输入const char*构造const std::string (例如const std::string("some literal"); ),C 字符串的副本存储在std::string

I'm trying to understand if (and why) the copy is required specifically in the case where the input C string is a string literal.我试图了解是否(以及为什么)在输入 C 字符串是字符串文字的情况下特别需要副本。 I would think that the std::string could simply refer to the string literal instead of creating a copy, so that the following code would only create "some literal" once.我认为std::string可以简单地引用字符串文字而不是创建副本,因此以下代码只会创建一次"some literal"

std::string str1("some literal");
std::string str2("some literal");

Certainly, performing a copy for C strings that aren't string literals is wise, because it allows the std::string to manage the lifetime of the data that it refers to.当然,对不是字符串文字的 C 字符串执行复制是明智的,因为它允许std::string管理它引用的数据的生命周期。 However, this is not an issue for string literals because they exist for the lifetime of the program.但是,这对于字符串文字来说不是问题,因为它们在程序的生命周期内都存在。

Also, since we are talking about const strings, we don't need to worry about the underlying data being changed during the program and breaking the value semantics of the std::string s.此外,由于我们在谈论const字符串,因此我们无需担心在程序期间更改底层数据并破坏std::string的值语义。 Well, at least as long as const_cast isn't used, but using const_cast is asking for trouble anyway, so I'm not too worried about that case.嗯,至少只要const_cast不使用,但使用const_cast是自找麻烦呢,所以我不会太担心这种情况。

So, is there any reason why the compiler can't optimize this case to have const std::string s refer to const char* s instead of creating copies?那么,编译器有什么理由不能优化这种情况,让const std::string s 引用const char* s 而不是创建副本? Alternatively, if the cppreference link was incorrect, and this optimization actually is implemented by some compilers, which compilers support this?或者,如果cppreference链接不正确,而这种优化实际上由一些编译器实现的,哪些编译器支持?

For the sake of this question, let's assume that the string literal is long enough that the small string optimization won't be a factor.为了这个问题,让我们假设字符串文字足够长,小字符串优化不会成为一个因素。

In your example, a std::string simply receives a pointer, it has no way of know what kind of memory that pointer is actually pointing at.在您的示例中, std::string只是接收一个指针,它无法知道该指针实际指向的内存类型。

The fact that the pointer is declared as pointing to const data is not relevant.指针被声明为指向 const 数据这一事实无关紧要。 A pointer to non-const data can be assigned to a pointer to const data (creating read-only access to otherwise writable data).可以将指向非常量数据的指针分配给指向常量数据的指针(创建对其他可写数据的只读访问)。

The std::string simply has no way of knowing that the pointer it is given is pointing at a string literal. std::string根本无法知道它给出的指针指向字符串文字。 The pointer could just as easily be pointing at an array on the call stack, or to a memory block allocated with new , or to memory owned by an external library.指针可以很容易地指向调用堆栈上的数组,或指向分配有new的内存块,或指向外部库拥有的内存。

There is nothing special about a narrow string literal, it is not some magic type that std::string could adjust its behavior for.窄字符串文字没有什么特别之处,它不是std::string可以调整其行为的某种魔法类型。 It is just a plain ordinary const char[] , just one whose memory is setup by the compiler/linker.它只是一个普通的const char[] ,它的内存是由编译器/链接器设置的。 It decays to const char * .它衰减为const char *

So std::string does the only sane and safe thing it can do given the lack of origin info - make a copy of the data.因此std::string在缺少原始信息的情况下做了它可以做的唯一理智和安全的事情 - 制作数据的副本。

That also keeps the implementation simple - the std::string always owns the data it holds.这也使实现变得简单—— std::string始终拥有它所持有的数据。

If you want a string-like container that doesn't own the data, just points at it, then look at C++17's std::string_view , or boost::string view for earlier compilers.如果您想要一个不拥有数据的类似字符串的容器,只需指向它,然后查看 C++17 的std::string_view ,或早期编译器的boost::string view

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 将字符串文字分配给std :: string - Assigning a string literal to std::string 将字符串文字指定给指向const char的指针 - Assigning string literal to pointer to const char 允许为std :: string分配“const char *”,但是不能编译分配给std :: wstring。 为什么? - Assigning a “const char*” to std::string is allowed, but assigning to std::wstring doesn't compile. Why? 在 c++ 中将 const std::string 分配给 std::string - Assigning const std::string to std::string in c++ 在 C++ 中将字符串文字传递给接受 const std::string &amp; 的函数时会发生什么? - What happens when a string literal is passed to a function accepting a const std::string & in C++? c ++传递字符串文字而不是const std :: string&? - c++ passing a string literal instead of a const std::string&? 从C ++的构造函数中向成员const char *变量分配字符串文字时会发生什么? - What happens when assigning a string literal to a member const char* variable from within a constructor in C++? 字符串文字的const限定词 - const qualifier for a string literal “ std :: string”或“ const std :: string&”参数? (该参数在内部复制和修改) - “std::string” or “const std::string&” argument? (the argument is internally copied and modified) 为什么不是 std::hash<const std::string> 专攻性病?</const> - Why isn't std::hash<const std::string> specialized in std?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM