[英]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.