2

调用TestComp的构造函数时出现编译错误,其设计如下:

template <typename R> 
class IComparable
{
public:
    virtual bool Equals(const R & rhs) const = 0;
};

class TestComp : IComparable<char*>
{
public:
    std::string x;

    TestComp(std::string & a)
    {
        x = a;
    }

    virtual bool Equals(const char* & a) const
    {
        return x == std::string(a);
    }
};

错误:

error C2259: 'TestComp2' : cannot instantiate abstract class due to following members:'bool IComparable<R>::Equals(const R &) const' : is abstract with [ R=char * ]

我无法理解,因为我正在定义 TestComp::Equals,其签名似乎与 IComparable::Equals 相同。

在尝试各种解决方法时我注意到的一件事是,如果我将两个函数都设为“Equals(R & rhs) const”,从参数中删除 const,那么我将不再收到此错误。

有人可以帮我理解这种行为吗?

4

2 回答 2

4

派生方法的签名不正确。它应该是

virtual bool Equals(char* const& a) const

请注意,const“应用于”下一个最接近的*and&和之前的类型&&,即

  • const char* &, 等价于char const* &, 表示对 的 const 指针的引用char

  • char* const&表示对指向 的指针的 const 引用char

  • const R&, 等价于R const&, 表示对 的 const 引用R

于 2013-10-01T07:48:46.950 回答
2
const R &

那是一个const引用(或者,学究式的,对一个const对象的引用)。

const char* & a

那是非const引用(指向const对象的指针);因此,它不会覆盖const引用的函数。您需要const对非const指针的引用:

char * const & a

const总是限定它之前的事物,除非它出现在开头,在这种情况下,它限定了第一件事。有些人建议养成将其始终放在符合条件的事物之后的习惯,即R const &而不是const R &,以稍微减少混淆的机会。

于 2013-10-01T07:51:10.517 回答