$10.3/5
「オーバーライド関数の戻り値の型は、オーバーライドされた関数の戻り値の型と同じか、関数のクラスと共変でなければなりません。関数 D::f が関数 B::f をオーバーライドする場合、関数の戻り値の型は次の基準を満たす場合、共変です。
— どちらもクラスへのポインタまたはクラスへの参照です98)
— B::f の戻り値の型のクラスは、D::f の戻り値の型のクラスと同じクラスであるか、D::f の戻り値の型のクラスの明確でアクセス可能な直接または間接の基本クラスです。 :f
—ポインターまたは参照の両方が同じ cv 修飾を持ち、D::f の戻り値の型のクラス型の cv 修飾が、B::f の戻り値の型のクラス型と同じか、cv 修飾が少ない。
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();
}
上記の実験的なコードを書いたところ、コモーのエラー/警告が矛盾していることがわかりました。9 行目の警告は、戻り値の型の cv 修飾子が無意味であることを示しているようです。そして、まさにこの理由が、コードの形式が正しくないことにつながります。
"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;}
^
問題は、コモーが 9 行目で「警告」メッセージを出すのは正しいかということです。私はそれが実装で定義された動作であることを知っています.Comeauは単に親切にしようとしています. しかし、この場合、せいぜい紛らわしいです。