有这样的课程:
#include <iostream>
#include <cmath>
class Element {
private:
int val;
public:
Element(int val_){ val = val_;}
friend Element std::pow(Element a, int exp);
};
我想覆盖标准函数pow,它是类Element的朋友,用于处理我的类的对象。但是,编译期间出现以下错误:
error: ‘Element std::pow(Element, int)’ should have been declared inside ‘std’
如何覆盖标准战俘功能?
答案 0 :(得分:7)
首先,您不是override
,而是overload
。术语override
与虚函数有关,overload
与基于参数类型选择正确的函数有关。
解决方案很简单:不写std::pow
,只写pow
。或yournamespace::pow
,如果您愿意 - 无所谓。是的,就是这样。
然后:
double a;
Element b;
using std::pow;
pow(a, 10.0); // calls std::pow(double, double)
pow(Element, 10) // calls pow(Element, int)
说明:在C ++中有一个叫做ADL(或Koenig的查找)的狂野的东西,它基本上决定使用哪个变体,并且它将从任何命名空间中选择重载,而不需要在调用的地方指定它。 / p>
阅读: http://en.wikipedia.org/wiki/Argument-dependent_name_lookup
答案 1 :(得分:2)
基本上,你不能这样做。首先,不允许您将用户定义的内容放在std
名称空间内。
您需要编写自己的pow
函数,该函数不在std
内。
答案 2 :(得分:0)
首先,您不应该向命名空间std
添加内容。
您的pow
重载应位于单独的命名空间中。你应该
using std::pow
using my::pow;
我支持的可辩论的样式点:像这样的泛型函数不应该是名称空间限定的。也就是说,使用using
并在客户端代码中调用pow()
而不是std::pow()
,同样适用于std::swap
和其他自定义点。
唯一可以扩展std
命名空间的是模板特化。再次考虑std::swap
。
答案 3 :(得分:-1)
您必须在标准命名空间中定义该函数,否则它不存在:
namespace std {
Element pow(Element a, int exp) {
//...
}
}