我重载了操作符<<在我自己的vector类中,它的工作方式如下
int main() {
my_vector<int> vec;
vec << 1 << 2 << 3; // will add elements at end [ 1, 2, 3 ]
display(vec);
}
这是我想要的完美工作,但我想让它更有效,我做了这个
10 << vec; // will add element at begin [ 10, 1, 2, 3 ]
但是当我多次这样做时就会出错,比如
20 << 10 << vec; // this does [ 20480, 1, 2, 3 ];
首先对20 <<10,然后20480 <<vec
我想把它处理成[20,10,1,2,3];
边注:
请不要以非预期的方式重载操作符。这将令人困惑,并将使您的代码难以阅读/维护。我无法想象在专业代码中会出现这样的过载,但这可能只是为了好玩。
在主题现在你的第二种方法不起作用,因为运算符:<<
>>
具有从左到右的结合律。这意味着当你写:
vec << 1 << 2 << 3;
这相当于:
(((vec << 1) << 2) << 3);
和
20 << 10 << vec;
实际结果是:
((20 << 10) << vec);
所以它首先计算20 << 10
,然后将其结果提供给您的操作符<<
的重载版本。
理论上,您可以重载其他具有从右到左结合性的操作符(例如<<=
,>>=
)来实现您的目标,但正如我指出的那样,这是非常糟糕的实践,这会使情况变得更糟。
一个可能的解决方案是创建一个代理对象,甚至是一个成熟的向量对象,它聚合要插入的元素。
接口看起来大概是这样的:
vec_front_inserter(20) >> 10 >> my_vec;
请注意,我建议使用提取操作符(>>
)来表示前插入,因为它对我来说读起来更好,但如果您不喜欢这样,可以随意更改回插入操作符(<<
)。
你的实现需要:
- 定义一个
operator>>(const my_vector&, my_vector&)
来表示一个向量插入另一个向量 - 创建一个定义了
operator>>(vec_front_inserter&, int)
的代理vec_front_inserter
类,并在内部持有my_vector
。 - 定义
operator>>(const vec_front_inserter&, my_vector&)
来插入my_vector
前面的元素。
class vec_front_inserter {
public:
vec_front_inserter() {}
vec_front_inserter(int seed) {
_data.push_front(seed);
}
friend vec_front_inserter& operator>>(vec_front_inserter& proxy, int value);
friend my_vector& operator>>(const vec_front_inserter& proxy, my_vector& vec);
private:
my_vector _data;
};
vec_front_inserter& operator>>(vec_front_inserter& proxy, int value) {
_data.push_back(value);
}
my_vector& operator>>(const vec_front_inserter& proxy, my_vector& vec) {
vec.insert_front(proxy._data);
}
我觉得这和字符串连接很相似。
你可以这样做:
std::string concat = std::string("foo") + "bar" + "biz" + "baz";
但是你不能这样做:
std::string fail = "foo" + "bar" + "biz" + "baz";
这是因为操作符的优先级/结合性。编译器首先执行<<20
和10
之间的操作,然后再执行一次<<结果与vec
之间的操作。这是因为如果您有多个<<
操作符,它们将从左到右进行处理。
使用括号可以解决这个问题:
20 << (10 << vec);
告诉编译器首先在10
和vec
之间执行操作,然后在结果和20
之间执行另一个操作。
(假设正确实现了操作符重载)。