I am experimenting with covariance and came up with the following example that does at least not compile with clang 11 and on 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;
};
It is related to Covariant return types, const-ness, and incomplete classes but not a duplicate because the constness is the same in both overwritten functions.
Is that even supported by the standard?
Is there a way to get around this problem or any suggestions to achieve a similar behavior?
While there may be workaround for what you're trying to achieve, the shown code is invalid.
According to class.virtual#9 :
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. ...
There's an example for this rule in the linked text.
In your case, since the return type of Odd::increment
is not Number
, and Even
is incomplete at the point of declaring Odd::increment
, the code is ill-formed.
I found the answer in this incorrect, and hence deleted answer written by @Brian in response to the question you've linked to.
You can achieve a similar thing with a non-virtual interface (though it has more lines and seems easier to mess up):
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());
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.