Reputation: 12613
Upon first glance, everything seems to be correct, but this code will NOT compile. However, if I were to change the return type of the base class to be double *
then it will compile. Can someone explain how/why the compiler does not see the template type "T" as a valid return type.
Base class:
01 template <typename T>
02 class DefaultValueFunctorBase {
03 public:
04 virtual const T operator() (void) const = 0;
05 };
Sub-class:
01 class DblPtrDft : public DefaultValueFunctorBase<double *> {
02 public:
03 DblPtrDft (double default_value_)
04 : DefaultValueFunctorBase<double *>(),
05 _default_value(default_value_),
06 _default_value_ptr(&_default_value)
07 {}
08
09 const double * operator() (void) const { return _default_value_ptr; }
10
11 private:
12 const double *_default_value_ptr;
13 const double _default_value;
14 };
ERROR:
DblPtrDft.h:09: error: conflicting return type specified for ‘virtual const double* DblPtrDft::operator()() const’ DefaultValueFunctorBase.h:04: error: overriding ‘const T DefaultValueFunctorBase::operator()() const [with T = double*]’
Upvotes: 1
Views: 2735
Reputation: 126412
The problem is that const T
should be read as T const
, which makes it clear that the const
qualifier applies to T
. Thus, when you replace T
with double*
in your template instantiation, what you get as the return type of the base class's call operator is double* const
.
This is different from the return type you have in the derived class's call operator (i.e. const double*
, which is equivalent to double const*
). In the superclass, you return a constant pointer to a double
. On the subclass, you return a non-constant pointer to a constant double
.
One way to fix your application is this:
template<typename T>
class DefaultValueFunctorBase
{
public:
// Do not return T const here: the top-level const is useless anyway
virtual T operator() (void) const = 0;
};
// Instantiate your base class template with double const* rather than double*
class DblPtrDft : public DefaultValueFunctorBase<double const*>
{
public:
DblPtrDft (double default_value_)
: DefaultValueFunctorBase<double const*>(), // Same change here of course...
_default_value(default_value_),
_default_value_ptr(&_default_value)
{}
// Return a double const*, consistently with the instantiated template...
double const* operator() (void) const { return _default_value_ptr; }
private:
double const*_default_value_ptr;
double const _default_value;
};
Upvotes: 4
Reputation: 185663
Your overridden function returns a const double *
, but the virtual function, with T = double *
, actually has a return type of double * const
.
Upvotes: 1