Виртуальная базовая функция с типом возвращаемого шаблона: сбой компилятора в производном классе с указателем типа в качестве аргумента шаблона (MSVC 2013)

Если я наследую от CBaseInterface (см. Код ниже) с шаблоном Argument T = int *, компилятор завершится ошибкой C2555. Это происходит со всеми типами указателей, используемых для T. Если я использую typedef вместо этого, тот же код работает нормально.

// If _FALIS is defined, the compiler fails, else it succeeds
// (MS Visual Studio 2013 Update 2, 32 and 64 Bit native C++, Debug build).
#define _FALIS

#ifdef _FALIS
#define PINT int*
#else
typedef int* PINT;
#endif

template <class T>
class CBaseInterface
{
public:
virtual ~CBaseInterface() {}
virtual const T Calculate() const = 0;
};

class CCalculator : public CBaseInterface<PINT>
{
public:
CCalculator() {}
virtual ~CCalculator() {}

// error C2555: 'CCalculator::Calculate':
// overriding virtual function return type differs and is not 'covariant'
// from 'CBaseInterface<int *>::Calculate'
virtual inline const PINT Calculate() const final
{
return (PINT)&m_Item;
}

protected:
int m_Item = 0;
};

Где проблема с типами указателей? Я в замешательстве и не нашел в документах Microsoft ничего такого, что бы соответствовало этой ситуации.

Надеюсь, ты сможешь мне помочь.

0

Решение

Разница заключается в значении const PINT в производном классе.

Если PINT является typedef для int *, затем const PINT является int * const (постоянный указатель на изменяемый int) — это нормально, это то, для чего определена функция базового класса. Если вы используете свой макрос, то у вас есть буквально const int * (изменяемый указатель на константу int), который является совершенно другим типом. Typedef логически подставляется в систему типов, макрос подставляется вслепую как токены.

Один из способов спасти это было бы написать PINT const или же const (PINT) (поэтому привязка const является явной).

И вы действительно не должны использовать макросы.

1

Другие решения


По вопросам рекламы [email protected]