在C ++中使用重载+添加2个向量

时间:2018-02-09 13:45:09

标签: c++ c++11

我正在尝试使用重载+运算符添加2个向量。 https://stackoverflow.com/a/4421719/9329547回答显示

inline X operator+(X lhs, const X& rhs)
{
  lhs += rhs;
  return lhs;
}

我的情况是我想将2个向量传递给类,然后一个函数将修改它们并使用另一个方法添加并返回它。这是代码。

class VO
{
private:

const std::vector<double> &vec1;
const std::vector<double> &vec2;

public:
VO (const std::vector<double> &x, const std::vector<double> &y): vec1(x), vec2(y) {}

std::vector<double> operator + (const std::vector<double> &, const std::vector<double> &) {}

std::vector<double> foo(....) 
{ 
//vectors vec1, vec 2 are modified here then want to add them
std::vector<double> v3 = vec1 + vec2;
return v3;
}
};

int main()
{
std::vector<double> a={1,2,3,4,5}, b={9,8,7,6,5},c;
VO obj(a,b);
c=obj.foo();
return 0;
}

在这种情况下,我不知道如何使用this添加2个向量。

编辑:

我可以在类中创建vectorAdd方法,传递2个向量并获得添加。但我想使用运算符+。运算符+在许多科学库中被重载以添加向量(数组)。

编辑2:

如果我使用原始代码,则会收到错误error C2804 binary operator + has too many parameters。我正在尝试添加2个向量,如果a={1,2,3,4,5}, b={9,8,7,6,5},则为a+b = {1+9, 2+8, 3+7, 4+6, 5+5} = {10,10,10,10,10}

3 个答案:

答案 0 :(得分:2)

您并不完全清楚自己想要实现的目标,但您似乎对如何以及为何使用运营商重载感到困惑。

  

我正在尝试使用重载+运算符

添加2个向量

好的,这个重载运算符的目的是你可以输入

vector<double> a, b, c;
// ... populate a and b ...
c = a + b;

好像 vector<double>是基本类型,如int或简单double

整点是为内置和用户定义类型获取相同的语法,以便稍后我们可以编写对两者都相同的通用代码。例如,std::plusstd::accumulate适用于定义了operator+任何类型,无论您是否添加整数或向量或其他内容。

要使其工作(并且操作符重载值得),在编写operator+时,必须通过常用的名称查找规则找到自定义a + b

然后你说

  

我想将2个向量传递给类,然后函数将修改它们并使用其他方法添加

但使用类方法而不是自由函数并不满足上述要求。当您输入V0::operator+时,找不到a + b。 (实际上V0::operator+无论如何只能作为向V0添加内容的方法,因为如果它是一种方法,它必须是非静态的,因此左侧将始终是V0对象)。

如果您仍然希望将其添加为V0的方法,则没有理由将其称为operator+,因为语法无论如何都不会相同。

相反,如果你想要相同的语法,它应该是一个自由函数,以便名称查找起作用。

你说你想要重载运算符,因为它在许多科学库中重载,但这并不能说明它希望它是一个类的方法而不是你的类型&# 39;重新添加

  • 如果你想使用其中一个库并提供operator+来使用它,那么将操作符放在一个不相关的类中就不会实现任何目标。在添加两个V0::operator+时,图书馆将如何知道应该致电vector<double>?那不是什么工作方式
  • 如果您想模仿这些库的样式,则与operator+类型相关联的唯一V0将用于添加V0个实例。它应该仍然是一个免费功能。

答案 1 :(得分:1)

以下是使用您链接的指南添加矢量的可能方法:

#include <iostream>
#include <vector>
#include <exception>

template<typename T>
std::vector<T>& operator+=(std::vector<T> &lhs, const std::vector<T> &rhs) {
    typedef std::vector<T>::size_type size_type;
    if (lhs.size() != rhs.size())
        throw std::length_error("vectors must be same size to add");

    for (size_type i = 0; i < lhs.size(); ++i)
        lhs[i] += rhs[i];
    return lhs;
}

template<typename T>
std::vector<T> operator+ (std::vector<T> lhs, const std::vector<T> &rhs) {
    typedef std::vector<T>::size_type size_type;
    if (lhs.size() != rhs.size())
        throw std::length_error("vectors must be same size to add");
    return lhs += rhs;
}

int main()
{
    std::vector<double> a = { 1,2,3,4,5 }, b = { 9,8,7,6,5 }, c;
    c = a + b;
    for (auto x : c)
        std::cout << x << ' ';
    return 0;
}

输出:

  
    

10 10 10 10 10

  

你可以定义一个数学向量类,它有一个std :: vector(因为没有虚拟析构函数),并在其上定义数学运算符,这样就不会在std :: vectors上意外调用这个运算符这不是数学向量。就个人而言,我会得到你提到的那些数学库之一,并使用它。无需重新发明轮子。

答案 2 :(得分:1)

矢量是固定类型。您不应该向其添加+

您可以像这样扩展矢量:

template<class T>
struct my_vector:std::vector<T> {
  using std::vector<T>::vector; // get vector's constructors

  my_vector& operator+=( my_vector const& rhs )& {
    if (size() < rhs.size()) resize(rhs.size());
    for (std::size_t i = 0; i < rhs.size(); ++i)
      (*this)[i] += rhs[i];
    return *this;
  }
  friend my_vector operator+( my_vector lhs, my_vector const& rhs ) {
    lhs += rhs;
    return lhs;
  }
  my_vector& operator*=( my_vector const& rhs )& {
    if (size() < rhs.size()) resize(rhs.size());
    for (std::size_t i = 0; i < rhs.size(); ++i)
      (*this)[i] *= rhs[i];
    return *this;
  }
  friend my_vector operator*( my_vector lhs, my_vector const& rhs ) {
    lhs *= rhs;
    return lhs;
  }
};

现在,使用my_vector<double>代替std::vector<double>

现在,您可以在您正在进行工作的命名空间中添加此operator+,但这通常不是一个好主意。对类型的操作应该是类型或类型命名空间的一部分,以避免意外。