2013-02-19 1 views
0

На первый взгляд все кажется правильным, но этот код НЕ компилируется. Однако, если бы я изменил тип возвращаемого значения базового класса на double *, тогда он будет скомпилирован. Может кто-нибудь объяснить, как/почему компилятор не видит тип шаблона «Т» в качестве действительного типа возврата.Ошибка C++: конфликтный тип возвращаемого значения, указанный для ... templated sub-class

Базовый класс:

01 template <typename T> 
02 class DefaultValueFunctorBase { 
03 public: 
04  virtual const T operator() (void) const = 0; 
05 }; 

Подкласс:

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 }; 

ОШИБКА:

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*]’

+3

двойных * сопз не совпадают с двойным сопзом * –

+0

@AndyProwl Можете ли вы сделать ответ и показать, что правильный код должен выглядеть? – Zak

+0

Сделай это, дай мне минуту. –

ответ

4

Проблема заключается в том, что const T следует читать как T const, что делает его ясно, что const классификатор относится к T. Таким образом, когда вы заменяете Tdouble* в своем экземпляре шаблона, то, что вы получаете как возвращаемый тип оператора вызова базового класса, - double* const.

Это отличается от типа возврата, который у вас есть в операторе вызова производного класса (т. Е. const double*, что эквивалентно double const*). В суперклассе вы возвращаете постоянный указатель на double. В подклассе вы возвращаете непостоянный указатель на константу double.

Один из способов исправить это приложение:

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; 
}; 
1

изменённая функция RET urns a const double *, но виртуальная функция, с T = double *, фактически имеет тип возврата double * const.

+0

Можете ли вы, пожалуйста, продемонстрировать, как должен выглядеть правильный код? – Zak

Смежные вопросы