Этот код успешно компилируется в g++ 6.1, но дает ошибку с clang 3.8:
class C;
class Base {
public:
virtual const C *getC();
};
class Derived : public Base {
public:
virtual C *getC();
};
Ошибка от clang выглядит следующим образом:
$ dev/compilers/linux-x86_64-2.12.2/clang3.8/bin/clang++ -Wall -c testcovariantreturn.cxx
testcovariantreturn.cxx:10:20: error: return type of virtual function 'getC' is not covariant with the return type of the function it overrides ('C' is incomplete)
Если класс C полностью определен, а не форвардно объявлен, ошибки не возникает. Мое понимание заключается в том, что ковариант допускает "меньшую" cv-квалификацию (т.е. Отбрасывание константы из возвращаемого типа) при переопределении виртуального метода.
Правильно ли clang/разрешено требовать полный тип, и если да, то почему? Как можно здесь изменить определение C?
Это не совсем академично, в большой базе кода, которую я неохотно добавляю в ненужные включения, мы пытаемся направить объявление как стандартную практику.