我有一个看起来像这样的课程:
class A {
public:
A() {};
A& operator<< (A& a, unsigned int i);
private:
vector<int> abc;
}
我希望能够使用运算符向abc
添加对象:
A a();
a << 3,4,5; // should do the same as several calls of abc.push_back(i)
我知道我必须重载<<
运算符,是否还必须重载,
运算符?
实际方法如何?
答案 0 :(得分:9)
永远不会在C ++中重载,
运算符。语言允许它,但你不能这样做并保留操作符的预期行为。 (特别是,逗号运算符是C ++中的一个序列点:编译器保证在右侧表达式之前计算左侧表达式。如果重载它,则不再保证将评估哪个表达式第一。)
您希望使用流插入运算符的多个调用来插入多个对象。
(为了完整性:你永远不应该重载的其他C ++运算符是&&
和||
。同样,不可能提供客户端代码期望的行为(在这种情况下,短路))
答案 1 :(得分:7)
如果您想保留a << 1, 2, 3
的方面,可以更改operator<<
的超载以接受initializer_list
int
,而不是int
#include <initializer_list>
class A {
public:
A() {};
A& operator<< (std::initializer_list<int> values);
private:
vector<int> abc;
}
}。
A& A::operator<< (std::initializer_list<int> values)
{
for(const auto& value : values)
abc.push_back(value);
return *this;
}
然后实现它:
A a;
a << {1, 2, 3, 4};
只需使用如下:
{{1}}
您唯一需要确保的是具有符合C ++ 11标准的编译器,它提供了这些功能。
答案 2 :(得分:1)
Eigen库实现了这种语法。不确定这是不是你来自哪里。
Eigen是一个表达式模板库。它定义了似乎可以执行操作的操作符和函数,但它们只是代理对象的工厂。代理形成编译时,有时是运行时数据结构,决定何时以及如何进行计算。
要实现此语法,您需要代理对象。可以类似于std::ostream
来考虑它。 a << 3
返回代理“stream”对象,然后重载operator ,
以启用, 4, 5
部分。代理也可以重载operator<<
,在这种情况下语法将是a << 3 << 4 << 5
。这可以说是更清晰,但是Eigen是一个数学和运算符重载密集型库,,
具有一个特殊的位置作为最低优先级的运算符,这减少了在{{{{{{ 1}}。
长话短说,即使你这样做,也应该坚持a << 3, true? 4 : 42, 5
。
operator<<