问题描述
我正在尝试协方差,并提出了以下示例,该示例至少不使用clang 11和VS2015进行编译:
class Number {
public:
virtual ~Number () = default;
virtual Number const * increment()const = 0;
};
class Even;
class Odd : public Number {
public:
// error: increment() is not covariant because Even is incomplete
Even const * increment()const;
};
class Even : public Number {
public:
Odd const * increment()const;
};
它与Covariant return types,const-ness,and incomplete classes有关,但不是重复的,因为两个重写函数的常量性相同。
该标准还支持吗?
解决方法
虽然您尝试实现的解决方法可能会变通,但是显示的代码无效。
如果D :: f的协变返回类型的类类型与B :: f的不同,则D :: f的返回类型的类类型应在该点完成D的声明:: f或应为类类型D ....
在链接的文本中有此规则的示例。
在您的情况下,由于Odd::increment
的返回类型不是Number
,并且在声明Even
时Odd::increment
是不完整的,因此代码格式错误
我发现答案不正确,因此是@Brian为您所链接的问题写的deleted answer。
,您可以使用非虚拟接口实现类似的操作(尽管它具有更多的行并且看起来更容易弄乱):
class Number {
public:
virtual ~Number() = default;
Number const * increment() const { return do_increment(); }
private:
virtual Number const * do_increment() const = 0;
};
class Even;
class Odd : public Number {
public:
Even const * increment() const;
private:
Number const * do_increment() const override;
};
class Even : public Number {
public:
Odd const * increment() const { return do_increment(); }
private:
Odd const * do_increment() const override;
};
inline Even const * Odd::increment() const {
return static_cast<Even const *>(do_increment());
}