Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std:: qualifier needed when overloaded namespace function exists?

If I have a little bit of code like:

using namespace std;

namespace myNamespace
{
    vector<float> sqrt( vector<float> v ) { return v; }

    void func()
    {
        vector<float> myVec = { 1, 2, 3, 4 };
        std::cout << sqrt( myVec )[0] << std::endl;
        float myFloat = 4.0f;
        std::cout << sqrt( myFloat ) << std::endl; // need to use std::sqrt()
    }
}

then it won't compile unless I changed the marked line to use std::sqrt. Why? I understand that if I tried to redefine sqrt(float) in myNamespace then I'd have to qualify with std:: if I wanted the standard library version to be used. The compiler appears to try to convert myFloat rather than just use a function in another (std) namespace.

One way I found to get around this is to define sqrt(vector<float>) in the std namespace but that doesn't quite feel right and answers to this question suggest overloading in std is illegal. Probably not the way to go then...

How can I overload sqrt (or any other standard library cmath function, for that matter) so that I don't have to always qualify which one to use and have the compiler select based on the passed function parameters?

Thanks.

like image 876
user2746401 Avatar asked Nov 19 '14 15:11

user2746401


People also ask

Should we use using namespace std in C++?

The statement using namespace std is generally considered bad practice. The alternative to this statement is to specify the namespace to which the identifier belongs using the scope operator(::) each time we declare a type.

Why is using namespace std a bad practice?

While this practice is okay for example code, pulling in the entire std namespace into the global namespace is not good as it defeats the purpose of namespaces and can lead to name collisions. This situation is called namespace pollution.

How do you call a namespace function in C++?

Namespaces in C++ You only need to prefix the function you wish to call with namespace_name:: -- similar to how you would call a static member function of a class. Another convenience of namespaces is that they allow you to use the same function name, when it makes sense to do so, to perform multiple different actions.


1 Answers

In C++, name lookup doesn't care about parameters type, only the name matters. When the compiler looks for a function named sqrt, it will always find your version first (since the lookup starts with the enclosing namespace), and stops there.

You must help the compiler by bringing the name from std:: into scope with a using directive in your namespace :

namespace myNamespace
{
  using std::sqrt
  ...
}

Then, standard overload resolution will take place to distinguish between your sqrt and std::sqrt, and will select the correct sqrt function to be called.

To avoid any ambiguity, you should always qualify the name (std::sqrt or myNamespace::sqrt)


Notes:

  • As pointed out by Simple, Argument Dependent Lookup (ADL) makes std::sqrt available for name lookup in the first case (since vector is in std::), but it doesn't change the problem you're facing.

  • Declaring your own sqrt function in std:: is a very bad idea (forbidden by the standard, except for template specializations)

like image 95
quantdev Avatar answered Sep 22 '22 12:09

quantdev