我有一个名为BaseSignal
的模板类,
template <class T>
class BaseSignal
{
public:
// Constructor
BaseSignal(long buf_size, bool is_async, SimData *sim)
....
从这个类派生出另外两个模板化的类:Net
和Reg
。(对于感兴趣的人,我将在Verilog中对并发和顺序赋值的行为进行建模)。它们被定义为
template <class T>
class Net : public BaseSignal<T>
{
public:
Net(long buf_size, bool is_async, SimData* sim)
: BaseSignal<T>(buf_size, is_async, sim) {};
....
对于Reg
也是如此。
在基类中,我将Set
和Get
方法定义为虚拟的,
// Virtual settors
virtual void Set(long val) {};
virtual void Set(double val) {};
// Virtual gettors
virtual void Get(long* val) const {};
virtual void Get(double* val) const {};
因为Net
和Reg
对这些有不同的行为。所以这里是有趣的部分。
+=重载在基类中工作
在基类中,我定义了这个操作符来调用虚拟的Set
和Get
操作,它按预期工作。
在BaseSignal
中
BaseSignal<T>& operator+=(const double& rhs)
{
T rval;
this->Get(&rval);
this->Set(rval + static_cast<T>(rhs));
return *this;
}
BaseSignal<T>& operator+=(const long& rhs)
{
T rval;
this->Get(&rval);
this->Set(rval + static_cast<T>(rhs));
return *this;
}
在我的代码中,我有指针net_real
和net_int
,当我这样做时
*net_real += 1.1;
*net_int += 1l;
净值正确递增。奇怪的是
=重载在基类中不起作用
正如预期的那样,在Net
类中重载=
工作得很好:
Net<T>& operator=(const double& rhs)
{
this->Set(static_cast<T>(rhs));
return *this;
}
Net<T>& operator=(const long& rhs)
{
this->Set(static_cast<T>(rhs));
return *this;
}
但如果我把这个放到BaseSignal
里
BaseSignal<T>& operator=(const double& rhs)
{
this->Set(static_cast<T>(rhs));
return *this;
}
BaseSignal<T>& operator=(const long& rhs)
{
this->Set(static_cast<T>(rhs));
return *this;
}
我可以很好地编译这个类文件,但是当我编译main.cpp
时,我得到的是:
ctests/main.cpp: In function 'int main()':
ctests/main.cpp:28:15: error: no match for 'operator=' (operand types are 'cpysim::Net<double>' and 'double')
28 | *net_real = 1.0;
| ^~~
In file included from ctests/main.cpp:9:
csrc/signals_nets.hpp:456:9: note: candidate: 'constexpr cpysim::Net<double>& cpysim::Net<double>::operator=(const cpysim::Net<double>&)'
456 | class Net : public BaseSignal<T>
| ^~~
csrc/signals_nets.hpp:456:9: note: no known conversion for argument 1 from 'double' to 'const cpysim::Net<double>&'
csrc/signals_nets.hpp:456:9: note: candidate: 'constexpr cpysim::Net<double>& cpysim::Net<double>::operator=(cpysim::Net<double>&&)'
csrc/signals_nets.hpp:456:9: note: no known conversion for argument 1 from 'double' to 'cpysim::Net<double>&&'
我不是100%确定我理解了“候选人”这部分。它是否正在尝试调用复制构造函数?更令人费解的是,为什么它适用于+=
而不是=
。
发布于 2019-06-24 09:13:23
这是一个隐藏名称的问题;派生类具有隐式生成的operator=
,包括copy assignment operator和move assignment operator,它们隐藏了基类的operator=
。
这就是name lookup的工作原理。当在派生类作用域中找到名称operator=
时,将不会检查包括基类作用域在内的其他作用域,名称查找将停止。之后,根据找到的名称执行重载解析,最终导致编译错误。
operator+=
没有这样的问题;派生类中没有(隐式或显式)声明的operator+=
。
您可以使用using
将基类的operator=
引入派生类作用域。例如:
template <class T>
class Net : public BaseSignal<T>
{
public:
using BaseSignal<T>::operator=;
...
};
https://stackoverflow.com/questions/56728781
复制相似问题