我试图重载向量的基本算术运算符。我们的想法是创建一个计算器,用于对非常长的数字进行加,减和乘以(例如,长度为4000)。当我添加两个向量时,我希望我的程序从两个向量的开头循环,添加值,然后将它们推送到第三个向量。我知道我不应该超载std类,或者我可以使用stl和boost来实现这一点,但我的项目不允许这样做。
我的主要问题是我的程序似乎无法识别我的重载运算符。这是一个代码段:
来自
//calculator.h
class Calculator {
public:
....
void Solve();
friend std::vector<int> operator+(const std::vector<int> &op1, const std::vector<int> &op2);
friend std::vector<int> operator-(const std::vector<int> &op1, const std::vector<int> &op2);
friend std::vector<int> operator*(const std::vector<int> &op1, const std::vector<int> &op2);
}
和
//calculator.cpp
void Calculator::Solve() {
...
if(operation == '-') {
op1 = op1 - op2;
}
else if(operation == '+') {
op1 = op1 + op2;
}
else if(operation == '*') {
op1 = op1 * op2;
}
...
}
friend std::vector<int> operator+(const std::vector<int> &op1, const std::vector<int> &op2) {
std::vector<int> toreturn;
...
//use a couple loops to add vectors together
...
return toreturn;
}
当我用g ++编译(-v = 5.4,ubuntu 16.04)时,我收到以下错误:
error: no match for ‘operator-’ (operand types are ‘std::vector<int>’ and ‘std::vector<int>’)
polynomial1 = polynomial1 - polynomial2;
^
In file included from /usr/include/c++/5/vector:65:0,
from Calculator.h:18:
/usr/include/c++/5/bits/stl_bvector.h:208:3: note: candidate: std::ptrdiff_t std::operator-(const std::_Bit_iterator_base&, const std::_Bit_iterator_base&)
operator-(const _Bit_iterator_base& __x, const _Bit_iterator_base& __y)
^
/usr/include/c++/5/bits/stl_bvector.h:208:3: note: no known conversion for argument 1 from ‘std::vector<int>’ to ‘const std::_Bit_iterator_base&’
In file included from /usr/include/c++/5/bits/stl_algobase.h:67:0,
from /usr/include/c++/5/vector:60,
from Calculator.h:18
我试图在全局范围内使向量重载(它们不能与Calculator类的私有成员一起工作),试图使它们成为成员函数(使用单个参数,{{1 }}和rhsObj
),将op1 = op1 + op2设置为this
。到目前为止,没有任何工作。我甚至尝试使用基本相同的代码创建公共函数std::vector<int> temp = op1 + op2
,但它还没有工作。
非常感谢任何帮助!
答案 0 :(得分:4)
您的代码无法编译,因为friend
声明仅使argument-dependent lookup的名称可用。
由于参数位于std
,因此只搜索运算符std
。您的功能不在std
中,因此找不到。
在您尝试将运算符添加到std
之前 - 不要,这是未定义的行为。
可以提供非朋友声明,以便在搜索封闭范围(see example - credit to BlackMoses)的常规查找步骤中找到这些名称。
然而,这在两个方面是个坏主意:
查找这些运算符会不一致;例如考虑this modification of the above code - 如果在较窄的命名空间中找到运算符名称,它将永远不会到达封闭的命名空间。因此,您应该只进行运算符重载,以便ADL找到它们(即至少有一个操作数与重载的运算符函数位于同一个类或命名空间中)。
无论如何,这对重载运算符的使用很差。如果包含您的代码的其他人不想要那些重载怎么办?而且他们对您班级的用户没有帮助。运算符重载的想法是为使用您的类的人提供直观的语法(在本例中为Calculator
)。您可以使用常规函数来实现类的成员函数。