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

问题描述 投票:0回答:2

我正在编写一个库来处理 2D 矩阵代数,使用矩阵内数据类型的模板,以便拥有最大的自由度并基本上处理我想要的任何类型数据的矩阵。

我想知道是否有某种方法可以重载

abs()
函数,以便将矩阵的行列式写为
abs(M);
,或者我是否必须使用另一个名称。我唯一关心的是矩阵的行列式与其绝对值相关(如标准符号所示),因此在我看来,重载绝对值函数以返回行列式是有意义的。

我已经尝试将其设为类方法,并使用

m.abs();
调用它,显然效果很好......但我希望该函数位于类之外,并获取矩阵作为参数,就像
int abs(int n);
功能有效。因此,我尝试重载该函数,但这给了我一些问题,因为
abs(n);
函数需要一些整数或长整型值作为参数,当然不是用户定义的矩阵。我也尝试将其设为班级的友元方法,但似乎没有帮助。期待您的建议。

c++ overloading
2个回答
0
投票

是否可以在C++中重载abs()

是的,虽然不推荐。原因如下:

  1. abs
    在命名空间
    std
    中定义,它是标准库的一部分。您应该在自己的另一个命名空间中编写自己的函数,例如
    Matrix
  2. abs
    通常用来计算数字的绝对值,这样的名字会让人困惑。

如果你仍然想这样做,你可以很容易地做到这一点:

struct Matrix {};

int abs(Matrix &m) { return /**/; }

int main() {
  Matrix m;
  int det = abs(m); // works fine
}

这里有一些可能的方法来实现你的

abs
(虽然我认为
det
可能是一个更好的名字):

1.
````cpp // 矩阵.h 命名空间矩阵 { 矩阵类 { /**/ };

int det(const Matrix&);
} // namespace matrix
```
  1. class Matrix {
        static int det(const Matrix&);
    };
    

0
投票

C++ 有一个名为“参数相关查找”的功能,专为此类需要在独立函数之间重载的情况而设计。典型的应用是重载 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);
}

© www.soinside.com 2019 - 2024. All rights reserved.