我正在编写一个库来处理 2D 矩阵代数,使用矩阵内数据类型的模板,以便拥有最大的自由度并基本上处理我想要的任何类型数据的矩阵。
我想知道是否有某种方法可以重载
abs()
函数,以便将矩阵的行列式写为 abs(M);
,或者我是否必须使用另一个名称。我唯一关心的是矩阵的行列式与其绝对值相关(如标准符号所示),因此在我看来,重载绝对值函数以返回行列式是有意义的。
我已经尝试将其设为类方法,并使用
m.abs();
调用它,显然效果很好......但我希望该函数位于类之外,并获取矩阵作为参数,就像int abs(int n);
功能有效。因此,我尝试重载该函数,但这给了我一些问题,因为 abs(n);
函数需要一些整数或长整型值作为参数,当然不是用户定义的矩阵。我也尝试将其设为班级的友元方法,但似乎没有帮助。期待您的建议。
是否可以在C++中重载abs()
是的,虽然不推荐。原因如下:
abs
在命名空间 std
中定义,它是标准库的一部分。您应该在自己的另一个命名空间中编写自己的函数,例如 Matrix
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
```
class Matrix {
static int det(const Matrix&);
};
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);
}