Is std :: qualifier necessary when there is an overloaded namespace function?

If I have some 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 will not compile unless I changed the highlighted line to use std::sqrt . What for? I understand that if I tried to override sqrt(float) in myNamespace , then I would have to qualify with std:: if I wanted to use the standard version of the library. The compiler seems to be trying to convert myFloat , and not just use the function in another ( std ) namespace.

One way to find this is to define sqrt(vector<float>) in the std , but this is not entirely correct and suppose the answer to this question is that overloading in std is illegal. This is probably not the way ...

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

Thanks.

+5
source share
2 answers

In C ++, a name lookup does not care about the type of parameters, only the name matters. When the compiler searches for a function called sqrt , it will always find your version first (since the search starts with the encompassing namespace) and stops there.

You should help the compiler by injecting the name from std:: into scope using using in your namespace:

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

Then, standard overload resolution will occur to distinguish between your sqrt and std::sqrt and 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 Search” (ADL) makes std::sqrt available to search for the name in the first case (since vector is in std:: , but it does not change the problem you are facing.

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

+9
source

You can bring std::sqrt to your namespace using the statement using std::sqrt; inside myNamespace :

 namespace myNamespace { vector<float> sqrt( vector<float> v ) { return v; } using std::sqrt; ... 

Then the compiler will select the appropriate sqrt in std::cout << sqrt( myFloat )

+2
source

Source: https://habr.com/ru/post/1207221/


All Articles