c++ 横向协变:return 类型因类型不完整而不同
c++ crosswise covariant: return type differs due to incomplete type
我正在试验协方差,并提出了以下示例,该示例至少不能使用 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;
};
它与 有关但不是重复的,因为两个被覆盖的函数中的常量是相同的。
标准支持吗?
是否有解决此问题的方法或任何实现类似行为的建议?
您可以使用 non-virtual 界面实现类似的功能(尽管它有更多的行并且看起来更容易搞砸):
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());
}
虽然您尝试实现的目标可能有解决方法,但显示的代码无效。
If the class type in the covariant return type of D::f differs from that of B::f, the class type in the return type of D::f shall be complete at the point of declaration of D::f or shall be the class type D. ...
链接文本中有此规则的示例。
在您的情况下,由于 Odd::increment
的 return 类型不是 Number
,并且 Even
在声明 Odd::increment
时不完整,代码是 ill-formed.
我在这个错误的答案中找到了答案,因此 deleted answer 由 @Brian 撰写以回应您链接到的问题。
我正在试验协方差,并提出了以下示例,该示例至少不能使用 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;
};
它与
标准支持吗?
是否有解决此问题的方法或任何实现类似行为的建议?
您可以使用 non-virtual 界面实现类似的功能(尽管它有更多的行并且看起来更容易搞砸):
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());
}
虽然您尝试实现的目标可能有解决方法,但显示的代码无效。
If the class type in the covariant return type of D::f differs from that of B::f, the class type in the return type of D::f shall be complete at the point of declaration of D::f or shall be the class type D. ...
链接文本中有此规则的示例。
在您的情况下,由于 Odd::increment
的 return 类型不是 Number
,并且 Even
在声明 Odd::increment
时不完整,代码是 ill-formed.
我在这个错误的答案中找到了答案,因此 deleted answer 由 @Brian 撰写以回应您链接到的问题。