问题
$10.3/5
"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 function D::f overrides a function B::f, the return types of the functions are covariant if they satisfy the following criteria:
— both are pointers to classes or references to classes98)
— the class in the return type of B::f is the same class as the class in the return type of D::f, or is an unambiguous and accessible direct or indirect base class of the class in the return type of D::f
— both pointers or references have the same cv-qualification and the class type in the return type of D::f has the same cv-qualification as or less cv-qualification than the class type in the return type of B::f.
struct A{};
struct B : A{};
struct X{
virtual const A * const f(){return 0;}
};
struct Y : X{
virtual const B * volatile f(){return 0;}
};
int main(){
Y b;
X &r = b;
r.f();
}
I wrote the above experimental code and find Comeau's error/warning to be inconsitent. The warning in Line 9 seems to indicate that cv qualifier in return type is meaningless. And it is this very reason which leads to the code being ill-formed.
"ComeauTest.c", line 5: warning: type qualifier on return type is meaningless
virtual const A * const f(){return 0;}
^
"ComeauTest.c", line 9: warning: type qualifier on return type is meaningless
virtual const B * volatile f(){return 0;}
^
"ComeauTest.c", line 9: error: return type is not identical to nor covariant with
return type "const A *const" of overridden virtual function function
"X::f"
virtual const B * volatile f(){return 0;}
^
So the question is, is Comeau right in giving the "warning" message at Line 9? I know that is an implementation defined behavior and Comeau is just trying to be nice. But in this case, it is at the best confusing.
回答1:
The warnings on lines 5 and 9 that the "type qualifier on return type is meaningless" are because non-class type rvalues are never cv-qualified.
Since the result of a function that returns by value is an rvalue and a pointer is a non-class type, the returned pointer is not cv-qualified, even if the return type says that it is.
This warning has nothing to do with covariance. The following function would cause the same warning:
int* volatile f() { return 0; }
As for the cited text from 10.3/5:
both pointers or references have the same cv-qualification
This is referring to the top-level qualification of the return type (that is, the volatile
in const int* volatile
). While the top-level qualification is meaningless, it does affect the type of the function, so given the declaration of f
above, this snippet is incorrect:
int* (*q)() = f; // error: can't convert int* volatile (*)() to int* (*)()
Likewise, if the top-level cv-qualification of the return type in the derived class member function does not match the top-level cv-qualification of the return type in the base class, the derived class member function does not override the base class member function.
the class type in the return type of
D::f
has the same cv-qualification as or less cv-qualification than the class type in the return type ofB::f
.
This is referring to the qualification of the class type of the return value (that is, the const
in const int* volatile
). This rule means that the qualification of the return type in the derived class member function must be equal to or less than that of return type of the base class member function that it overrides.
来源:https://stackoverflow.com/questions/3593601/covariant-return-type