С cppreference :
Если функция Derived::f
переопределяет функцию Base::f
, их типы возврата должны быть одинаковыми или ковариантными.
Существует три условия, которые должны быть выполнены для ковариантности двух типов, и одно из них заключается в том, что они должны быть либо указателем, либо ссылочным типом.
A<int>
и B<int>
не являются ни тем же типом, ни ковариантным типом, что означает, что вы не можете использовать B<int>
в качестве типа возврата вашего переопределенного метода.
Обратите внимание, что вам не нужно использовать спецификатор virtual
в вашем переопределенном методе.
Более того, как заметили и другие, сработает следующее и вернет объект A<int>
:
A<int> func() override
{
return B<int>{};
}
Но вам следует избегать этого. Фактически, после создания B<int>
объекта он будет нарезан на тип A<int>
, по причинам, которые мы видели, то есть тип вашего объекта будет просто A<int>
, а не экземпляр B<int>
. Это означает, что вы бесполезно создали экземпляр B<int>
, когда вы могли просто создать A<int>
.
Если вам нужен B<int>
, вам нужно будет вернуть либо указатель, либо ссылку.