Z jakiegoś powodu aktualne wersje zarówno GCC, jak i klang nie rozpoznają kowariancji typu powrotu w tym konkretnym scenariuszu. Komunikat o błędzie jest myląca:Typ zwracania kowariantu nie jest rozpoznawany
error: return type of virtual function 'foo' is not covariant with the return
type of the function it overrides ('derived *' is not derived from 'base *')
Oto kod:
class base
{
private:
virtual base * foo() = 0;
};
template< class T >
class foo_default_impl : public virtual base
{
private:
T * foo() override { return nullptr; }
};
class derived : public virtual base, private foo_default_impl<derived>
{
};
int main() {
derived d{}; // error: return type of virtual function 'foo' is not covariant with the return type of the function it overrides ('derived *' is not derived from 'base *')
return 0;
}
'foo()' musi zwrócić 'foo_default_impl *', a nie 'T *'. –
czy poprzednie wersje skompilowały twój kod? Zastanawiam się, czy to dlatego, że 'wyprowadzony' nie jest jeszcze pełnym typem, gdy jest przekazywane do foo_default_impl: http://eel.is/c++draft/class.derived#class.virtual-8 – marcinj
@KhouriGiordano: Dlaczego? W szczególnym przypadku, który rozważamy, 'T' będzie" wyprowadzony ", a" wyprowadzony "jest publicznie wyprowadzony z' base'. –