在C++中可以重载abs()吗?

uqxowvwt  于 2023-08-09  发布在  其他
关注(0)|答案(2)|浏览(131)

我正在编写一个库来处理2D矩阵代数,使用矩阵内数据类型的模板,以便尽可能自由地处理矩阵,基本上,我想要的任何类型的数据。
我想知道是否有某种方法可以重载abs()函数,以便将矩阵的行列式写成abs(M);,或者我是否必须使用另一个名称。我唯一关心的是矩阵的行列式与其绝对值有关(正如标准符号所示),因此在我看来,重载绝对值函数以返回行列式是有意义的。
我已经试着把它变成一个类方法,用m.abs();调用它,显然效果很好……但我希望函数在类的外部,并将矩阵作为参数,就像int abs(int n);函数一样。所以,我试图重载这个函数,这给我带来了一些问题,因为abs(n);函数需要一些整数或长值作为参数,而不是用户定义的矩阵。我也试着让它成为类的朋友方法,但似乎没有什么帮助。期待您的建议。

uurity8g

uurity8g1#

C++有一个名为argument-dependent lookup的特性,它是为这样的情况而设计的,即您希望在独立函数之间进行重载。典型的应用程序是重载std::swap,但这里也可以使用它。

#include <cmath>
// using std::abs
#include <iostream>

namespace my_ns {

class Matrix
{};

float abs(const Matrix&)
{
    std::cout << "Calling abs(Matrix)\n";
    return 0.f;
}

} /* namespace my_ns */

int main()
{
    my_ns::Matrix mat;
    std::cout << abs(mat) << '\n';
}

字符串
输出量:

Calling abs(Matrix)
0


关键点是在调用abs时不指定名称空间。如果调用std::abs(mat),它将失败。但是,如果您编写using std::abs,它仍然有效。这对于模板很有用,这样您就可以将std::abs用于标准类型,也可以在自己的名称空间中使用自己的abs

template<class T>
auto call_abs(const T& value)
{
    using std::abs;
    return abs(value);
}

dm7nw8vv

dm7nw8vv2#

在C++中是否可以重载abs()
是的,虽然不推荐。其原因如下:

  1. abs是在命名空间std中定义的,而命名空间std是标准lib的一部分。您应该在自己的另一个命名空间(如Matrix)中编写自己的函数
  2. abs通常用于计算一个数的绝对值,这样的名称会令人混淆。
    如果您仍然想这样做,您可以很容易地做到这一点:
#include <cmath>

struct Matrix {};

namespace std {
int abs(const Matrix &m) { return 0; }
} // namespace std

int main() {
  Matrix m;
  int det = std::abs(m);
}

字符串
下面是一些实现abs的可能方法(尽管我认为det可能是一个更好的名字):

// Matrix.h
namespace matrix {
class Matrix { /**/ };

int det(const Matrix&);
} // namespace matrix


或者:

class Matrix {
    static int det(const Matrix&);
};

相关问题