If I derive from CBaseInterface (see code below) with template Argument T=int*, the compiler fails wirh error C2555. This happens with all pointer types used for T. If I use a typedef instead, the same code works fine.
// 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;
};
Where is the problem with the pointer types? I am confused and I didn't find anything in Microsoft's docs that fits at this Situation.
Hope you can help me.
The difference is to do with the meaning of
const PINT
in the derived class.If
PINT
is a typedef forint *
, thenconst PINT
is anint * const
(constant pointer to mutable int) - which is fine, that's what the base class function is defined to return. If you use your macro then you have literallyconst int *
(mutable pointer to constant int), which is a completely different type. The typedef is substituted logically into the type system, the macro is substituted blindly as tokens.One way to rescue this would be to write
PINT const
orconst (PINT)
(so the binding of the const is explicit).And you really shouldn't use macros.