Search code examples
c++stdoverloadingcmath

Is it a good practice to overload math functions in namespace std in c++


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).

So I have the following class:

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

And I can use it this way:

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);

Compiler (g++ (Debian 4.7.2-5)) error is: "no matching function for call to sqrt(ns::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;
}

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 ?

Is there a better alternative ?


Solution

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

    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.