I have a container and want to rely on whoever uses my library to make sure that a function is available for the underlying value_type (pow() in the coming example). And I want the compiler to use that function inside of a member function with the same name, based on its signature.
My attempt to create a minimal example:
#include <iostream>
#include <cmath>
using std::pow;
template <typename T>
struct container {
T value;
container<T> pow(T const exp) const {
return {pow(this->value, exp)};
}
};
int main() {
container<double> value{81.};
std::cout << value.value << "^0.25 = " << value.pow(.25).value << '\n';
return 0;
}
The container<> offers a pow() method, that is supposed to rely on pow() being available from the underlying type in the global namespace.
This is supposed to facilitate the use of custom number-like types. I.e. library users should be able to define their own types that act like numbers and supply a pow() function for their type, to make it container<> compatible.
The problem, neither clang nor gcc pick up the function from the global namespace:
c++ -std=c++11 pow.cpp -o pow
pow.cpp:11:28: error: too many arguments to function call, expected single argument 'exp', have 2 arguments
return {pow(this->value, exp)};
~~~ ^~~
pow.cpp:17:50: note: in instantiation of member function 'container<double>::pow' requested here
std::cout << value.value << "^0.25 = " << value.pow(.25).value << '\n';
^
pow.cpp:10:2: note: 'pow' declared here
container<T> pow(T const exp) const {
^
If I use the global namespace explicitly, it works as expected:
container<T> pow(T const exp) const {
return {::pow(this->value, exp)};
}
And the program produces the expected output:
c++ -std=c++11 pow.cpp -o pow
./pow
81^0.25 = 3
That solves the actual problem, but I wonder why it is necessary? Shouldn't the signature match allow the compiler to select the right function?