我在尝试从父结构继承函数调用操作符时遇到问题。我创建了一个简单的代码来说明我的问题:
#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()...
答案 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;。