私は、単に派生クラスメンバ関数ポインタを、基本クラスメンバ関数ポインタにキャストできない理由を理解しています(here)。純粋な仮想メンバをベースにしたキャスト派生仮想オーバーライド
しかし、このスニペット与えられた:私がお聞きしたかった
struct base
{
virtual void foo() = 0;
};
struct derived : base
{
void foo() override {};
};
struct invoker
{
typedef void(base::*target)();
invoker(base* b, target t)
{
(b->*t)();
}
};
template<typename B, typename D>
void (B::*cast(void (D::*method)()))()
{
return static_cast<void(B::*)()>(method);
}
derived d;
invoker bad(&d, &derived::foo); //C2664
invoker good(&d, cast<base>(&derived::foo));
は、コンパイラが、それは純粋仮想メソッドで理解し、そしてそれが階層間でどこかに実装されますので、基本関数のシグネチャを飾るすることが可能です(そうでなければ、タイプB
のオブジェクトを構築できませんでした)?私はなぜこれを通常の関数で行うことができないのか理解していますが、純粋な仮想関数の場合にはコンパイラには実装が保証されています。(完了していない場合はクラスB
に関するエラーが発生します。キャスト)。
あなたが求めている装飾の種類は不明です。あなたがC++デザイン委員会の最高責任者だったら、どうしますか?一貫性や正確性を心配する必要はありません.C++に追加したいものだけを表示してください。 'derived :: foo'が' base'に存在することをコンパイラに伝えたいのであれば、単に '&base :: foo'と書くことができます。 –
@ n.m。私は明示的なキャストを避けたい:Dしかし、それは "私が認識していない何らかの方法がある"という質問のタイプであった。 –
いいえ、キャストしないでください。 '&base :: foo'から始めましょう。 '&derived :: foo'は'&base :: foo'でできないものは何ですか? –