Search code examples
c++covariance

c++ crosswise covariant: return type differs due to incomplete type


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?


Solution

  • 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.