首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在C++中使用重载+添加2个向量

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

Stack Overflow用户
提问于 2018-02-09 13:45:09
回答 3查看 2.7K关注 0票数 1

我试图使用重载的+运算符添加两个向量。https://stackoverflow.com/a/4421719/9329547答案显示

内联X operator+(X,const & rhs) { lhs += rhs;返回lhs;}

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

代码语言:javascript
运行
复制
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:

如果我使用我的原始代码,我会得到错误的error C2804 binary operator + has too many parameters。我试图添加两个向量,如果是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}

EN

回答 3

Stack Overflow用户

发布于 2018-02-09 18:41:39

目前还不完全清楚您想要实现什么,但是您似乎很困惑如何以及为什么要使用操作符重载。

我试图使用重载+运算符添加两个向量

好的,这个重载运算符的目的是您可以键入

代码语言:javascript
运行
复制
vector<double> a, b, c;
// ... populate a and b ...
c = a + b;

就好像vector<double>是一个原始类型,如int或简单的double

关键是要为内置类型和用户定义类型获得相同的语法,这样以后我们就可以编写对两者都同样工作的泛型代码。例如,std::plusstd::accumulate适用于任何定义了operator+的类型,无论您是在添加整数、向量还是其他东西。

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

然后你说

我想将两个向量传递给类,然后一个函数将修改它们,并使用另一个方法进行添加。

但是使用类方法而不是使用空闲函数并不能满足上述要求。键入V0::operator+时将找不到a + b。(实际上,V0::operator+只能是一种向V0添加东西的方法,因为如果它是一个方法,它必须是非静态的,所以左侧总是一个V0对象)。

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

相反,如果您确实希望使用相同的语法,那么它应该是一个空闲函数,以便名称查找工作。

您说要重载运算符,因为它在许多科学库中被重载,但这并不能解释为什么希望它是类的方法,而不是要添加的类型。

  • 如果您想使用其中一个库并提供一个operator+来使用,那么将操作符放在一个无关的类中是不会有任何效果的。当添加两个V0::operator+时,库如何知道它应该调用vector<double>?任何事情都不是这样的
  • 如果您想模仿这些库的样式,那么与您的operator+类型关联的惟一V0将用于添加V0实例。它仍然应该是一个自由的功能。
票数 3
EN

Stack Overflow用户

发布于 2018-02-09 17:15:48

下面是向量添加的一个可能实现,使用您所链接的指南:

代码语言:javascript
运行
复制
#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

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

票数 1
EN

Stack Overflow用户

发布于 2018-02-09 19:16:48

向量是一种固定类型。您不应该向它添加+

您可以像这样扩展向量:

代码语言:javascript
运行
复制
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+添加到您正在工作的名称空间中,但这通常不是一个好主意。对类型的操作应该是类型的一部分或类型的命名空间中的一部分,以避免意外。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48707284

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档