【发布时间】:2018-03-15 05:24:25
【问题描述】:
有没有办法让 [] 运算符在左值和右值上下文中的处理方式不同?
示例代码:
include <stdio.h>
class test {
public:
unsigned a;
unsigned const & operator [](unsigned const idx) const;
unsigned & operator [](unsigned const idx);
};
unsigned const & test::operator [](unsigned const idx) const {
printf("const [%u] called\n", idx);
return a;
}
unsigned & test::operator [](unsigned const idx) {
printf("non-const [%u] called\n", idx);
return a;
}
int main() {
test t;
unsigned a;
a = 0;
printf("a = %u\n", a);
t[0] = a;
printf("stored a to t[0]; a = %u\n", a);
a = t[0];
printf("read a from t[0]; a = %u\n", a);
}
t[0] = a; 有 lvalue-context [] 运算符,a = t[0]; 有 rvalue-context [] 运算符,但它们都是通过非常量函数处理的。我还尝试声明 unsigned const & test::operator [](unsigned const idx) 方法,但它没有编译并说不允许这种重载。有没有办法(我需要它)通过 t[0]=a; 和 a=t[0]; 的不同处理程序来处理 [] 运算符?
请不要将此标记为与C++ Operator Overloading [ ] for lvalue and rvalue 重复,因为此问题不一样,即使看起来相似。
添加了可能也相关的简化代码: 包括
class test {
public:
unsigned a;
unsigned const & operator [](unsigned const idx) const;
/*unsigned & operator [](unsigned const idx);*/
};
unsigned const & test::operator [](unsigned const idx) const {
printf("const [%u] called\n", idx);
return a;
}
/*unsigned & test::operator [](unsigned const idx) {
printf("non-const [%u] called\n", idx);
return a;
}*/
int main() {
test t;
unsigned a;
a = t[0];
printf("read a from t[0]; a = %u\n", a);
}
我注释掉了非常量运算符 [],删除了对 t[0] 的写入,现在它编译并使用了 [] 所需的方法。但是一旦我取消注释非常量,它就会开始使用它并忽略前一个。换句话说,问题是:有没有办法在所有可能的地方让 const 优先于非 const ?
【问题讨论】:
-
阅读ref-qualified functions cppref 链接实际上可能不是最好的资源
-
在这两种情况下,
t肯定是一个左值。您似乎在询问区分对t的读写访问权限。在这种情况下,您可能想要使用代理 - 请参阅 stackoverflow.com/questions/30806786/… -
在 C++ 中,“左值”和“右值”并不真正意味着更传统的“赋值左侧”和“赋值右侧”。
-
不幸的是,引用限定函数没有帮助 - 如果存在,它仍然对这两种情况使用左值一。至于代理类——我知道有可能,但对于这样一个简单的问题,它看起来编码太多了:(。是的,它是对
t的读写访问,但从编译器的角度来看,它应该是读取的——只有对[]返回的值的读写访问。