Предупреждения в строках 5 и 9 о том, что «квалификатор типа в возвращаемом типе не имеет смысла», связаны с тем, что не относящиеся к классу значения типа r никогда не указываются в cv.
Поскольку результатом функции, возвращающей значение, является значение rvalue, а указатель относится к неклассному типу, возвращаемый указатель не квалифицирован cv, даже если возвращаемый тип говорит, что это так.
Это предупреждение не имеет ничего общего с ковариацией. Следующая функция вызовет то же предупреждение:
int* volatile f() { return 0; }
Что касается процитированного текста из 10.3 / 5:
оба указателя или ссылки имеют одинаковую квалификацию cv
Это относится к квалификации верхнего уровня типа возвращаемого значения (то есть volatile
в const int* volatile
). Хотя квалификация верхнего уровня не имеет смысла, она влияет на тип функции , поэтому, учитывая объявление f
выше, этот фрагмент неверен:
int* (*q)() = f; // error: can't convert int* volatile (*)() to int* (*)()
Аналогично, если cv-квалификация верхнего уровня возвращаемого типа в функции-члене производного класса не соответствует cv-квалификации верхнего уровня возвращаемого типа в базовом классе, функция-член производного класса не переопределяет функция-член базового класса.
тип класса в типе возврата D::f
имеет ту же квалификацию cv, что и квалификация cv или меньше, чем тип класса в типе возврата B::f
.
Это относится к квалификации типа класса возвращаемого значения (то есть const
в const int* volatile
). Это правило означает, что квалификация возвращаемого типа в производной функции-члене класса должна быть равна или меньше, чем квалификация возвращаемого типа функции-члена базового класса, которую она переопределяет.