具有模板返回类型的虚拟基本函数:编译器在派生类处失败,并以pointertype作为模板参数(MSVC 2013)

时间:2014-06-01 09:49:08

标签: c++ templates pointers derived covariant

如果我使用模板Argument T = int *从CBaseInterface(参见下面的代码)派生,编译器将失败,错误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;
};

指针类型的问题在哪里?我很困惑,我在微软的文档中找不到适合这种情况的任何内容。

希望你能帮助我。

1 个答案:

答案 0 :(得分:1)

不同之处在于派生类中const PINT的含义。

如果PINTint *的typedef,则const PINTint * const(指向mutable int的常量指针) - 这很好,这就是基类函数被定义为返回。如果你使用你的宏,那么你就有const int *(指向常量int的可变指针),这是一种完全不同的类型。 typedef在逻辑上被替换为类型系统,宏被盲目地替换为标记。

解决此问题的一种方法是编写PINT constconst (PINT)(因此const的绑定是明确的)。

你真的不应该使用宏。