有没有办法让[]运算符在左值和右值上下文中以不同的方式处理?
示例代码:
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 []运算符,但它们都是通过非const函数处理的。我还尝试声明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);
}
我注释掉了非const运算符[],删除了写入t [0],现在它编译并使用[]所需的方法。但是,一旦我取消注释非const,它就开始使用它并忽略前一个。换句话说,问题是:在可能的所有地方,有没有办法让const优先于非const优先?
答案 0 :(得分:1)
不,是的。
不,上下文不能改变C ++中操作符或函数的返回类型。
是的,您可以使用伪引用伪造它。
伪引用是一个重载operator =(T const&)&&
和operator T()&&
的对象。
struct pr_unsigned { // lazy name, do better
unsigned* target;
void operator=(unsigned const& in)&&{ *target=in; }
operator unsigned()&&{ return *target; }
pr_unsigned(pr_unsigned&&)=delete;
};
这是一个玩具,但是:
pr_unsigned test::operator [](unsigned const idx) { return {&a}; }
我们现在为test[2]=3;
和foo=test[0];
提供了不同的代码路径。
这远非完美的模仿; auto x = test[2];
做错了。但它并不可怕。
您可以在test*
中存储unsigned idx
和pr_unsigned
,并在将元素分配到/来自test
时运行任意代码。