c++ - 在 C++ 中重载命名空间 std 中的数学函数是一种好习惯吗

标签 c++ std overloading cmath

我正在编写一个表示算术类型的 C++ 类(围绕 mpfr 的 C++ 包装器),我想支持 中的一些函数(我将以 std::sqrt 为例).

所以我有以下类(class):

namespace ns
{
  class MyClass
  {
      /* ... */
      public:
      friend MyClass sqrt(const MyClass& mc);
  };
}

我可以这样使用它:

MyClass c;
/* ... */
MyClass d = ns::sqrt(c);
MyClass e = sqrt(c); // Apparently I don't have to specify ns::

但我不能这样使用它:

MyClass f = std::sqrt(c);

编译器 (g++ (Debian 4.7.2-5)) 错误是:“没有匹配函数调用 sqrt(ns::MyClass&)”。

这很正常,但对我来说是个问题。我需要它是有效的,因为 MyClass 应该用于现有的模板函数(我不应该修改)。例如:

template <typename T>
void func(T a)
{
    /* ... */
    T c = std::sqrt(a);
    /* ... */
}
int main()
{
    func<float>(3);
    func<MyClass>(MyClass(3));
    /* ... */
}

下面这段代码实际上解决了我的问题:

namespace std
{
  using ns::sqrt;
}

但在 std 命名空间中添加东西对我来说似乎很不自然。这样做我怕以后会遇到意想不到的麻烦。

安全吗?如果不是,为什么?

还有更好的选择吗?

最佳答案

标准禁止向命名空间 std 添加内容。解决这个问题的正确方法通常是 swap(在 std 命名空间中可用,但可以通过用户定义的类型进行专门化以更有效地工作) :当需要使用模板函数时,例如sqrt,就可以了

using std::sqrt;
a=sqrt(b);

这样,对于“常规”类型,它将使用 std::sqrt(通过 using 语句“接受”),而对于您的类型,您的重载将以Koenig lookup为准(顺便说一句,这就是您在 //显然我不必指定 ns:: 处观察到的行为的原因)。

关于c++ - 在 C++ 中重载命名空间 std 中的数学函数是一种好习惯吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22701354/

相关文章:

c++ - 为什么 "using namespace std;"被认为是不好的做法?

c++ - std::is_convertible 与 std::function 不一致

c++ - 运算符 () 重载模板 C++

Kotlin:可以在编译期间通过元编程修改函数吗?

c++ - 清除已经为空的 vector 会导致未定义的行为吗?

C++ 输出运算符重载

c++ - boost::multiprecision::float128 和 C++11

c++ - 创建非默认可构造类的虚拟对象

c++ - 当我尝试编译这个 C++ 程序时,它给了我一个错误

c++ - 如何获得像旋转一样的玛雅人?