在C ++中的命名空间std中重载数学函数是否是一个好习惯 [英] Is it a good practice to overload math functions in namespace std in c++

查看:89
本文介绍了在C ++中的命名空间std中重载数学函数是否是一个好习惯的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在写一个表示算术类型的C ++类( mpfr 的c ++包装器),我希望支持在< cmath>中找到的某些功能.(我将以std :: sqrt为例).

I am writing a C++ class which represents an arithmetic type (a c++ wrapper around mpfr), and I'd like to support some functions found in <cmath> (I'll take std::sqrt as an example).

所以我有以下课程:

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::

但是我不能这样使用它:

But I cannot use it this way:

MyClass f = std::sqrt(c);

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

Compiler (g++ (Debian 4.7.2-5)) error is: "no matching function for call to sqrt(ns::MyClass&)".

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

This is normal, but it's a problem to me. I need this to be valid, because MyClass is supposed to be used into existing template functions (that I'm not supposed to modify). For example:

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

以下代码实际上解决了我的问题:

The following piece of code actually resolve my problem:

namespace std
{
  using ns::sqrt;
}

但是对我来说,将东西添加到std命名空间中似乎很不自然.恐怕以后会遇到意想不到的麻烦.

But adding things into the std namespace seems very unnatural to me. I am afraid to run into unexpected troubles later, doing this.

安全吗?如果没有,为什么?

Is it safe ? If not, why ?

还有更好的选择吗?

推荐答案

这不安全,因为它不合法(第17.6.4.2.1节):

It’s not safe, because it’s not legal (§17.6.4.2.1):

如果C ++程序的声明或定义添加到名称空间 std 或名称空间 std 中的名称空间中,则该行为不确定,除非另有说明.仅当声明依赖于用户定义的类型且该专业化满足原始模板的标准库要求且未被明确禁止时,程序才可以将任何标准库模板的模板专业化添加到名称空间 std 中.

The behavior of a C++ program is undefined if it adds declarations or definitions to namespace std or to a namespace within namespace std unless otherwise specified. A program may add a template specialization for any standard library template to namespace std only if the declaration depends on a user-defined type and the specialization meets the standard library requirements for the original template and is not explicitly prohibited.

因此,您可以为自己的类型添加特殊化.您可能添加重载(或其他任何内容).

So you may add specialisations for your own types. You may not add overloads (or indeed anything else).

您当前的代码是执行此操作的正确方法.

Your current code is the correct way of doing this.

这篇关于在C ++中的命名空间std中重载数学函数是否是一个好习惯的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆