C++ - 基于赋值侧重载 [] 运算符
我正在尝试用 c++ 编写一个动态数组模板,
我目前正在重载 [] 运算符,并且我想根据它们使用的赋值的哪一侧来实现不同的行为。
#include <iostream>
...
template <class T>
T dynamic_array<T>::operator[](int idx) {
return this->array[idx];
}
template <class T>
T& dynamic_array<T>::operator[](int idx) {
return this->array[idx];
}
using namespace std;
int main() {
dynamic_array<int>* temp = new dynamic_array<int>();
// Uses the T& type since we are explicitly
// trying to modify the stored object
(*temp)[0] = 1;
// Uses the T type since nothing in the array
// should be modified outside the array
int& b = (*temp)[0];
// For instance...
b = 4;
cout<<(*temp)[0]; // Should still be 1
return 0;
}
由于显而易见的原因,当尝试像这样重载时,我会遇到编译器错误。
有没有正确的方法来做到这一点?
到目前为止我的搜索还没有成功。我所看到的重载 [] 运算符似乎都接受用户可以修改对象外部的存储项。
我已经实现了使用 (instance(int i), update(int i, T obj)) 的方法,但如果能够像常规数组一样使用此类,那就太好了。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您不能仅重载返回类型。
提供常量和非常量访问器重载的标准方法是通过
this
的常量来区分:对于常量版本,您可以返回常量引用或按值返回,具体取决于
>T
是 - const-reference 可能更普遍有用。(当然,您可以编写
operator[](std::size_t i)
来代替get()
。我只是想保持简短。)我不知道我不认为这能 100% 实现您的想法,但那是因为您的推理有误:
int b = foo()
将永远成为对任何内容的引用,即使foo()
返回一个(常量或非常量)引用,因为b
被声明为int
类型,而不是int& ;
。实际上,当您说 int b = (*temp)[0]; 时,您实际上会调用非常量版本,但这实际上并不是问题。 (要获得常量版本,您必须说int b = static_cast &>(*temp)[0];
或(*static_cast<; const dynamic_array *>(temp))[0]
- 但何苦呢。)You cannot overload only on return type.
The standard way to provide constant and non-constant accessor overloads is to differentiate by the constness of
this
:For the constant version, you can return either a const-reference or by value, depending on what
T
is - const-reference is probably more universally useful.(In place of
get()
you would writeoperator[](std::size_t i)
, of course. I just wanted to keep it short.)I don't think this achieves 100% what you had in mind, but that's because you have an error in your reasoning:
int b = foo()
will never be a reference to anything, even iffoo()
returns a (const or non-const) reference, becauseb
is declared to be of typeint
, notint&
. Practically, you would actually call the non-const version when you sayint b = (*temp)[0];
but that isn't actually a problem. (To get the constant version, you'd have to sayint b = static_cast<const dynamic_array<int> &>(*temp)[0];
or(*static_cast<const dynamic_array<int> *>(temp))[0]
- but why bother.)Scott Meyers 在一本《Effective C++》书中谈到了这一点。基本上,技巧是从索引运算符(
operator[]()
和operator[]() const
)返回一个临时常量或非常量代理对象,然后重载该代理类的赋值和隐式转换运算符。像这样的事情:我可能有一些细节错误,但想法是推迟决定元素位于分配的哪一侧,直到实际尝试分配给它。也就是说,您不知道在调用operator[]时会做什么,但当您尝试分配给后续元素引用时,您肯定会知道。
Scott Meyers talked about this in one of the Effective C++ books. Basically the trick was to return a temporary const- or non-const proxy object from the index operators (
operator[]()
andoperator[]() const
), then overload the assignment and implicit conversion operators for that proxy class. Something like this:I may have some of the details wrong but the idea is to defer the decision of what side of the assignment the element is on until an actual attempt is made to assign to it. That is, you don't know what will be done at the time of the operator[] call, but you certainly do when you attempt to assign to the subsequent element reference.