覆盖作为班级朋友的标准功能

时间:2011-07-28 13:43:22

标签: c++

有这样的课程:

#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’

如何覆盖标准战俘功能?

4 个答案:

答案 0 :(得分:7)

首先,您不是override,而是overload。术语override与虚函数有关,overload与基于参数类型选择正确的函数有关。

解决方案很简单:不写std::pow,只写powyournamespace::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) {
        //...
    }
}