Override standard function which is friend of class
There is such class:
#include <iostream>
#include <cmath>
class Element {
private:
int val;
public:
Element(int val_){ val = val_;}
friend Element std::pow(Element a, int exp);
};
I'd like to override standard function pow, which is friend of class E开发者_开发技巧lement, to work with objects of my class. However, there is following error during compilation:
error: ‘Element std::pow(Element, int)’ should have been declared inside ‘std’
How to override standard pow function?
First of all, you don't override
, you overload
. The term override
relates to virtual functions, and overload
to choosing the right function basing on parameter types.
The solution is simple: don't write std::pow
, just write a pow
. Or yournamespace::pow
, if you prefer - doesn't matter. Yes, it's just that.
Then:
double a;
Element b;
using std::pow;
pow(a, 10.0); // calls std::pow(double, double)
pow(Element, 10) // calls pow(Element, int)
Explanation: In C++ there's a wild thing called ADL (or Koenig's lookup) which will basically decide which variant to use, and it will choose the overload from any namespace without you needing to specify it at the place of the call.
Have a read: http://en.wikipedia.org/wiki/Argument-dependent_name_lookup
Basically, you can't do this. For one thing, you are not allowed to put user-defined things inside the std
namespace.
You will need to write your own pow
function, that is not inside std
.
Well for as start you shouldn't be adding things to namespace std
.
Your pow
overload should be in a separate namespace. You should then be
using std::pow
using my::pow;
Debatable style point that I endorse: generic functions like this should not be namespace-qualified. That is to say, use the using
and call pow()
in client code instead of std::pow()
, same applies to std::swap
and other customisation points.
The only time you can extend the std
namespace is with template specialisations. Again, consider std::swap
.
You have to define the function in the standard namespace, or else it does not exist:
namespace std {
Element pow(Element a, int exp) {
//...
}
}
精彩评论