如何重载 == 运算符来比较犰狳向量?

Posted

技术标签:

【中文标题】如何重载 == 运算符来比较犰狳向量?【英文标题】:How Can I Overload The == Operator to Compare Armadillo Vectors? 【发布时间】:2021-04-13 10:57:37 【问题描述】:

在我的程序中,我使用了许多arma::uvecs,并像这样检查它们之间的相等性

#include <armadillo>
using Vec = typename arma::uvec;
Vec v1(0, 0);
Vec v2(0, 1);
bool are_equal = arma::all(v1 == v2);

因为我找不到更好的相等运算符in the Armadillo docs。现在效果很好,但是为了节省一些空间,并且作为子类化和运算符重载的练习,我想在向量之间定义等号 直接,如下所示:

class Vec : public arma::uvec 
    friend bool operator==(const Collapsed& lhs, const Collapsed& rhs) 
        return arma::all(lhs == rhs);
    
;

但遗憾的是,我无法让它像那样工作。我很感激任何提示!

【问题讨论】:

你的实现会很好我认为如果你不把它放在一个子类中,而是作为一个全局函数。在我看来,您误解了 friend 的作用。 谢谢!事实是:我完全不明白friend 做了什么。没有它就行不通,然后我得到一个朋友的提示,要在 friend 前面加上(不是双关语)。 啊,好吧,friend 不是用来实现功能的。我在答案中放了一些链接 【参考方案1】:

运算符重载不需要是类的一部分。我建议将您的比较运算符实现为这样的免费函数:

bool operator==(const arma::uvec& lhs, const arma::uvec& rhs) 
    return arma::all(lhs == rhs);

关于您的问题中的friend:作为一个快速总结,它提供了对朋友声明所在类的私有和受保护成员进行友好访问的功能。它不用于实现功能。 您可以在cppreference 或this SO question 上阅读更多相关信息

编辑 由于上述仅在 operator== 尚未定义的情况下才有效,因此这里有一个版本,它覆盖了自定义子类的实现:

class Vec : public arma::uvec

public:
    bool operator==(const Vec& other)
    
        // depending on wether arma implemets operator== as member or free function
        // return arma::all(this->arma::uvec::operator==(other));
        return arma::all(arma::operator==(*this, other));
    

;

【讨论】:

实际上,它会抛出一个error: no matching function for call to 'all',正如我评估的那样,因为我们在定义它的两个对象之间使用了== 运算符,在它自己的定义中。有没有其他我们可以使用的运算符,或者我们可以重新定义它而不使用它吗? operator== 内的 lhs == rhs 显然是一个递归。需要一些强制转换来强制使用不同的运算符重载。 啊,是的,我没想到。在这种情况下,我们可以为您自己的Vec 类定义运算符。那现在需要是子类而不是别名。 其实我们也需要继承构造函数。到目前为止,我不知道如何从this SO post 放置using uvec::uvec; 对继承构造函数不起作用吗?【参考方案2】:

问题是库本身:

Armadillo: C++ library for linear algebra & scientific computing

运营商:+  −  *  %  /  ==  !=  &lt;=  &gt;=  &lt;  &gt;  &amp;&amp;  ||

MatColRowCube 类的重载运算符

操作:+两个对象相加

一个对象从另一个对象中减去或否定一个对象

*两个对象的矩阵相乘;不适用于 Cube 类,除非乘以标量

% 两个对象的元素乘法(舒尔积)

/ 一个对象被另一个对象或标量按元素划分

== 两个对象的元素相等性评估; 生成 umat/ucube

类型的矩阵/立方体

!= 两个对象的元素不等式评估;生成 umat/ucube

类型的矩阵/立方体

uvec 是:

uvec = ucolvec = Col&lt;uword&gt;

所以operator== 已经存在,它的功能很奇怪/出乎意料。

我的建议是:不要与图书馆争吵。不要尝试提供自己的运营商。只需提供一个命名函数areEqual

定义一个类只是为了提供自己的相等运算符不是一个最佳选择,如果这样做,那么 IMO 最好使用组合而不是继承(根据要求,类本身将是更多样板代码,但它会是更容易避免意外行为)。

【讨论】:

以上是关于如何重载 == 运算符来比较犰狳向量?的主要内容,如果未能解决你的问题,请参考以下文章

在 C++ 中重载比较运算符会导致“无效运算符<”

C++如何重载指针的比较符

广播类似于 Numpy 的犰狳矩阵运算的最佳方式

包含复数的向量的运算符重载

为啥会出现分段错误/如何重载运算符?

我想在运算符重载函数中从向量中删除一个元素