函数调用运算符的继承和重载

时间:2014-01-16 17:23:34

标签: c++ inheritance operator-overloading

我在尝试从父结构继承函数调用操作符时遇到问题。我创建了一个简单的代码来说明我的问题:

#include <iostream>
using namespace std;

template <class T, int N>
struct array
{
    T value[N];
    T& operator() (int);
};

template <class T, int N>
T& array<T,N>::operator() (int i)
{ return value[i]; }

template <class T, int N>
struct matrix: public array<T,N*N>
{
    T& operator() (int,int);
};

template <class T, int N>
T& matrix<T,N>::operator() (int i, int j)
{ return this->value[i*N+j]; }

int main()
{
    matrix<double,100> a;
    a(0) = 3.5;
    cout << a(0) << endl;
    return 0;
};

我希望'matrix'类从'array'类继承operator(),并用本地operator()重载它;我希望这是因为参数的数量不同。但是,这段代码的编译失败了,例如“错误:不匹配调用'(矩阵)(int)'”和“注意:候选人需要2个参数,1提供”。如果operator()没有在类'matrix'中定义,则继承正常发生,代码编译并运行正常,如预期的那样。

我做错了什么?我不想不必要地重新定义operator()...

3 个答案:

答案 0 :(得分:5)

名称查找在C ++中的工作方式,在编译器找到名称的那一刻,它就会停止查找。换句话说,编译器首先在operator()中找到matrix并停止查找,永远不会在array中找到它。

您可以使用using声明明确地将基础operator()带入范围:

template <...>
struct matrix : public array<...> {
  using array::operator();
  T& operator ()(int, int);
}

答案 1 :(得分:1)

当您声明具有给定名称的成员函数时,它将屏蔽所有具有相同名称的继承函数。这意味着默认情况下它不会超载它们,即使参数数量不同,或者它们的类型不同等。

但是,您可以使用using声明将基类功能带入子类的范围。在您的情况下,将其放在matrix班级的某处:

using array<T, N*N>::operator ();

答案 2 :(得分:1)

通过重载派生类中的基类函数,您已经隐藏了基类函数。要访问基类函数,您必须重新定义基类函数&#34; T&amp; operator()(int)&#34;在派生类中,您可以使用&#34;使用array :: operator();&#34;。