I have a templated class called BaseSignal
,
template <class T>
class BaseSignal
{
public:
// Constructor
BaseSignal(long buf_size, bool is_async, SimData *sim)
....
From this class are derived two other templated classes, Net
and Reg
. (For those interested, I am modeling the behavior of concurrent and sequential assignments in Verilog). These are defined as
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) {};
....
and similarly for Reg
.
In the base class, I have defined the Set
and Get
methods as virtual,
// 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 {};
As the Net
and Reg
have different behaviors for these. So here's the interesting part.
+= Overloading Works in the Base Class
In the base class, I define this operator to call the virtual Set
and Get
operations, which works as expected.
In the 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;
}
In my code, I have pointers net_real
and net_int
and when I do
*net_real += 1.1;
*net_int += 1l;
The net values increment correctly. Here's the weird part
= Overloading Is Not Working in the Base Class
Overloading =
in the Net
class works fine, as expected:
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;
}
But if I put this in 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;
}
I can compile the class file fine, but when I compile main.cpp
, I get this:
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>&&'
I'm not 100% sure I understand the "candidate" part. Is it trying to call the copy constructor? And I also don't get why there is no match with operands (operand types are 'cpysim::Net<double>' and 'double')
, since Net
is derived from BaseSignal
, and I have defined the operator for these operands. Even more puzzling is why it works for +=
and not =
.