为什么字符串文字不是prvalue
Why string literal is not prvalue
我一直在浏览价值类别。向我解释为什么字符串文字不是prvale
当表达式没有身份但可移动
时,我已经了解表达式的值/结果已属于prvalue
类别 int i=42;char i='a'; //prvalue
string i ="notprvalue";
字面的" notprvalue"没有身份和可移动属性吗?
字符串文字无法移动。它们是基本类型的数组,因此,举动与副本无法区分。
和字符串文字具有脱离物体对象的身份,因为它们的寿命超过了本地范围(另一个原因无法从中移动)。这就是为什么您可以从函数中返回文字的const char*
并仍然进行程序工作。另外,如果文字具有相同的字符串,则两个字符串文字可以指的是相同的字符数组(它们的指针可能相同)。因此," bar"answers" bar"可能指向相同的内存。
字符串文字是一种幻想。它们似乎是基本类型,例如int
或char
或指针。但是它们不是。
通常,它们不能直接加载到寄存器中。当然,指向他们的指针可能是。但是它们也不是指针。它们是数组,内部被用作指针,可以腐烂成指针,但数组不仅仅是这样,例如他们跟踪sizeof
操作员的大小。数组不是基本类型。
c字符串的类型文字不是char const*
甚至char *
,而是C 中的char const[]
(或C中的char[]
)。如果不是这种情况,sizeof
操作员将无法在字符串字面上正确工作:sizeof "Lorem ipsum dolor sit amet"
是26而不是8。指针,对现代系统的尺寸持续:4或8个字节(取决于系统是32还是32或64位)。那不是您做sizeof(my_string_literal)
时想要的。
因此,字符串文字是匿名的char
的数组,但您可以通过文字本身神奇地指它们。从技术上讲,这可能不是正确的,但是我喜欢将字面本身视为一种"身份"。(当然是在哈希之后)对于存储在程序段中的实际字符数组。
您还可以创建一个可写入的char
的数组,然后使用字符串字面的字符串初始化:char my_string[] = "my string literal"
初始化,您实际在做的是将匿名char const[]
的元素复制到新的char[]
中。
字符串文字实际上是恒定的吗?在C 中。但是它们在C中没有正式实施,但是现代编译器不必尊重您修改它们的尝试,因此可以执行的行为不确定:char* my_string_pointer = "some literal"; my_string_pointer[5] = 'k';
,但要执行char[] my_string_array = "some literal"; my_strig_array[5] = 'k'
非常好。前者初始化A 指针。后者通过复制来初始化 array 。
因此,字符串文字是lvalues,即使在技术上未用作const
,您也应该将其视为const
。
理解所有这些的关键是,rvalues不是必不可少的基本字体类型。它们也可能是非基础的非文字临时工,例如:int answer = my_class().compute_something()
用于struct my_class{ int data; int compute_someting(){ // ... compute ... } };
在此代码中,临时创建了my_class
的实例,以评估其发生的表达式。通过对其创建LVALUE身份,它将扩大一生。但是,由于我们不这样做,所以这只是发生的陈述。在包含它的代码线结束时,它已经死了。因此,这是一个rvalue。现在,从实施方面,这就像一个短暂的匿名lvalue,当它获得"物有意义"时。在表达中。这就是为什么如果要初始化或将其分配给可以这样做的另一个LVALUE,则应该能够从中移动。因此,某些rvalues实际上像LVALUE一样可疑,但匿名和较短。正是这种见解导致了" xvalues"。并移动语义:完成时手动标记LVALUE作为临时性的能力,因此我们可以通过使用std::move
铸造它来移动它。
顺便说一句,可以考虑到" pure rvalues"。从某种意义上说,它们不是被std::move
铸造而成为RVALUE的LVALUE,而是从一开始就一直是Rvalues,即临时。字符串文字不是暂时的,因此它不是prvalue。字符串文字也不是xvalues,因为它们甚至在程序运行之前永久地生活在程序的数据段中 - 在磁盘上。
请参阅基思·汤普森(Keith Thompson)关于修改字符串文字以获取更多洞察力的答案:修改字符串文字
- constexpr 函数中的非文字(通过 std::is_constant_evaluated)
- 我可以使用条件运算符初始化C风格的字符串文字吗
- 如何使用字符串文字作为宏参数
- 有没有办法从非C/C++文件中读取C++原始字符串文字的内容
- 构造<int>具有 2 个字符串文字的向量
- 将数字打印成文字
- 初始化或分配空字符串文字到指向 C 中的 char 的指针或指向 C++ 中 const char 的指针的原因是什么
- 方便地对C++中的所有字符串文字进行模糊处理
- 返回指向对象的指针的函数调用是否为 prvalue?
- 一元*运算符的操作数是否期望一个 prvalue
- C++17 十六进制浮点文字单精度后缀冲突?
- 常量函数,当其参数是对文字类型的引用时
- 连接 LPCSTR 变量和文字?
- 使用 prvalue 创建shared_pointer
- 初始化声明符是 prvalue 表达式吗?
- 比较 std::string 和 C 样式字符串文字
- 如何从char16_t字符串文字中读取双精度?
- 指内置类型的文字
- 分配给浮点数的积分文字除法 - 为什么结果是错误的?
- 为什么字符串文字不是prvalue