7
An example where one is overriding POD return type without const
in the derived class:
struct B1
{
virtual const int* f();
};
struct D1 : B1
{
int* f() override;
};
Compilers like Clang and GCC raise a warning:
invalid covariant return type for ‘virtual int* D1::f()’
When same scenario is applied but return type is some struct/class, no warning is raised:
struct S
{
};
struct B2
{
virtual const S* f();
};
struct D2 : B2
{
S* f() override;
};
I compiled this on different compilers and versions (Clang and GCC).
I would have expected similar warning when struct/class pointer is returned in the derived class when not using const
declaration.
1
1 Answer
Reset to default
5
The behaviour you observe is consistent with the Standard. From this Draft C++17 Standard#:
13.3 Virtual functions ┬а┬а┬а┬а┬а [class.virtual]
тАж
8 ┬а┬а┬а The
return type of an overriding function shall be either identical to the
return type of the overridden function or covariant with the classes
of the functions. If a functionD::f
overrides a functionB::f
,
the return types of the functions are covariant if they satisfy the
following criteria:(8.1) ┬а┬атАФ both are
pointers to classes, both are lvalue references to classes, or both
are rvalue references to classes
(8.2) ┬а┬атАФ the
class in the return type ofB::f
is the same class as the class in
the return type ofD::f
, or is an unambiguous and accessible direct
or indirect base class of the class in the return type ofD::f
(8.3) ┬а┬атАФ both pointers or references have the same
cv-qualification and the class type in the return type ofD::f
has
the same cv-qualification as or less cv-qualification than the class
type in the return type ofB::f
.
So, in your second case, all three of the above criteria are met. Note that 8.3 is true because the pointers returned are not cv-qualified тАУ the const
refers to the pointed-to object, not the pointer itself. If you instead declare the base class function as virtual S* const f();
then the derived class version you have will no longer be valid. Further, the return type in your derived class function is less cv-qualified than in the base class; swapping the definitions so that the base class is virtual S* f();
and the derived is const S* f() override;
will also make it invalid.
However, in your first snippet, the returned type of the function does not meet the 8.1 criterion (int
is not a class); thus, in order to be a valid override, its return type must be identical to that of the base class version.
# The text hasn’t changed significantly in the latest, online draft.
2
-
Interestingly, removing
override
still leaves OP's code with a hard error, instead of silently not overriding the function.– HolyBlackCat11 hours ago
-
1
@HolyBlackCat depends. Some compilers whine about incorrect ambigous overloading in that case (function overloads can't differ by return type alone). Once upon a time I believed that this cryptic message alone was the reason for
override
keyword as an extension.– Swift – Friday Pie6 hours ago
Not the answer you're looking for? Browse other questions tagged
or ask your own question.
or ask your own question.
How did you get a warning from Clang? Mine doesn't warn: gcc.godbolt.org/z/3TsW5Mqvo
11 hours ago
|