为啥文字不是 const (字符串除外)?
Posted
技术标签:
【中文标题】为啥文字不是 const (字符串除外)?【英文标题】:Why are literals not const (except strings)?为什么文字不是 const (字符串除外)? 【发布时间】:2018-08-29 12:16:22 【问题描述】:文字通常是prvalue
s。
字符串是一种特殊情况,定义为char
(意思是lvalue
)的数组。
这个问题专门针对 not string 文字。
为什么非字符串文字不是const
?
foo(42); // passes foo an `int`, not a `const int`.
您不能修改非字符串文字,所以将其设为 const
是否有意义?
【问题讨论】:
您是否想到了一个重要的用例? 函数参数上的*** const 限定符无论如何都会被丢弃(即void foo(const int)
与void foo(int)
相同)。那么它会有什么不同呢?
不是重复的 - 标题明确排除了字符串文字,所以关于字符串文字的问题字面上不能重复。
我真的想不出有什么办法让这个有所作为,除了字面上写decltype(42)
。你能详细说明它会带来什么吗?
历史事故。在 C 中,您可以修改和不能修改的内容完全取决于所讨论事物的值类别(左值是可修改的,右值不是),但需要注意的是修改字符串文字(左值)是 UB,它是一个类型系统疣。因此,当 C++ 尝试解决此问题时,它会将 const
添加到字符串文字的类型中,以使其静态不可修改。其他文字一开始是静态不可修改的,因此没有人认为有必要将它们设为const
。
【参考方案1】:
字面的答案可能是因为文字早于const
添加到语言中,所以它们自然不是const
。
但实际的答案是 - const
prvalues 从根本上说是奇怪的东西。您不能从任何基本类型创建它们,但您可以拥有类类型的const
prvalue。但为什么?通常,我们制作const
以防止进一步修改正确。但如果它是一个prvalue,它甚至不是一个有身份的东西——谁会在那里观察它的意外修改? const
prvalues 阻止移动 - 因为它们是 const
,所以你不能离开它们,所以它是过早的悲观。
请注意,可能出错的一件事,即假设的 const
文字会阻止,该语言已经明确禁止:
void foo(int&);
foo(42); // error
但是,该语言没有使42
const
成为左值引用,而不是const
不允许绑定到右值。
【讨论】:
【参考方案2】:请记住,默认情况下 C++ 是传递值,这意味着值是复制。
没有办法修改像 42 这样的数字文字值,因为您所拥有的只是变量中的副本。文字值本身甚至不必存储在内存中,编译器可以直接在生成的代码中使用它。
【讨论】:
“没有办法修改数字文字值” - 那为什么不是const
?
@IvanRubinson 因为你不能做42 = 5
?根本没有必要使数字文字保持不变,因为它们本质上已经是不变的。将数字文字存储在变量中后,您将拥有该数字文字的 副本,您可以根据需要修改该副本,因为它不再是原始文字值。
“没有必要让数字文字保持不变,因为它们本质上已经是” - 这闻起来很腥。如果它本质上是const
,为什么不是const
?
@IvanRubinson 看来你没有在听。最后一次,一旦你将一个数字文字值放入一个变量中,它就是你使用的 变量,而不是文字本身!数字文字是prvalue,它们永远不能位于赋值的左侧。您无法获取(指向)数字文字的地址,语言中无法修改。
@IvanRubinson - 因为成为一个纯右值就足够了。它不是一个对象,它只是一个(模糊的)值,可以用来创建一个对象。以上是关于为啥文字不是 const (字符串除外)?的主要内容,如果未能解决你的问题,请参考以下文章