string和vector的下标运算符的求值结果是否为左值

c++primer里说string和vector的下标运算符的求值结果为左值,但两者的下标运算符重载后不是返回了对该位置元素值的引用吗?这样返回的结果和左值的定义不是冲突了吗,左值的定义不是要求用的是对方的内存位置吗?

左值表示你可以把它放到=左边对它赋值。(non-const)下标运算符返回的是元素值的引用,可以对其赋值,因此是左值。而const下标运算符返回的是元素值的拷贝,是一个临时变量,不能对其赋值,故不是左值,而是右值。

下标 a[b] 是 R& T::operator[](S b);
R& T::operator[](S1 s1, ...);

(C++23 起)
N/A
解释
内建的 下标 (subscript) 运算符提供对它的指针或数组操作数所指向的对象的访问。

内建的 间接寻址 (indirection) 运算符提供对它的指针操作数所指向的对象或函数的访问。

内建的 取地址 (address of) 运算符创建指向它的对象或函数操作数的指针。

对象的成员 和 指向对象的成员的指针 运算符提供对它的对象操作数的数据成员或成员函数的访问。

内建的 指针的成员 和 指向指针的成员的指针 运算符提供对它的指针操作数所指向的类的数据成员或成员函数的访问。

内建的下标运算符
下标运算符表达式的形式为

表达式1 [ 表达式2 ] (1)
表达式1 [ { 表达式, ... } ] (2) (C++11)
表达式1 [ 表达式2 , 表达式, ... ] (3) (C++23)

  1. 对于内建运算符,表达式之一(表达式1 或 表达式2)必须是“T 的数组”类型的泛左值或“T 的指针”类型的纯右值,而另一表达式(分别是 表达式2 或 表达式1)必须是无作用域枚举或整型类型的纯右值。此表达式的结果类型是 T。 表达式2 不能是无括号的逗号表达式。 (C++23 起)
  2. 方括号中有花括号环绕列表的形式只能用于调用重载的 operator[]。
  3. 方括号中有逗号分隔的表达式列表的形式只能用于调用重载的 operator[]。
    内建下标表达式 E1[E2] 除了求值顺序之外 (C++17 起)与表达式 *(E1 + E2) 严格等同,就是说,它遵循指针算术的规则,将指针操作数(可以是数组到指针转换的结果,但它必须指向某数组的元素或末尾后一位置)调整成指向同数组的另一元素,然后再进行解引用。

应用到数组时,如果数组是左值,那么 (C++11 起)下标表达式是左值,否则是亡值 (C++11 起)。

应用到指针时,下标表达式始终是左值。

对啊,因为是引用所以是原来的内存位置