2017-09-13 6 views
4

メンバへのポインタへのアクセスに使用されるポインタが正しい型である限り、次のことは未定義の動作につながりますか?派生クラスへのポインタメンバ変数をポインタベースのクラスメンバ変数にキャストするのは合法でしょうか?

もしそうなら、なぜキャストが必要なのですか?それがなければもっと良く見えます(そして、はい、それは単なる意見の問題です)。

struct base { 
    int foo(int base::* ptr) { 
     return this->*ptr; 
    } 
}; 

struct sub : base { 
    int blah{ 42 }; 
}; 

int main() { 
    return sub{}.foo(static_cast<int base::*>(&sub::blah)); 
} 
+1

ここでは正式なのか分かりませんが、大変**安全です**。あなたは 'int'メンバを持たないオブジェクトに対して' foo'を呼び出すことができます。それを行う。別の言い方をすれば、正式なUBではないことを知っていれば、本当の問題を助長しません。タイプは安全ではないので、UBかどうかは言語弁護士の質問以外では無関係です(しかし、興味のあるものとしてタグ付けすることを検討してください)。この方法で解決しようとしている問題は何ですか? –

+0

私はまだ問題を解決しようとはしていません。私は最近、それを広範囲に使用するいくつかのコードを使って作業を始めました。パターンはまったくうまく座りません。 – evan

答えて

6

限りへのポインタメンバにアクセスするために使用されているポインタが正しい型であるとして、未定義の動作を次のようにリードしていますか?

いいえ、整形式です。 [expr.mptr.oper]からルールは、である:E1の動的タイプE2が参照するメンバーが含まれていない場合

は、動作は未定義です。 *this

dynamic typeメンバーが含まれていた、subあるので、これは結構です。

もしそうなら、なぜキャストが必要ですか?

それは本質的に危険なキャストだし、経験則では、本質的に危険な操作が大声で可視でなければならないことですので。この特定のケースでは、それは問題ありませんが、それはあなたが慎重であったからです。キャストを要求することで、あなたはそれについて考える必要があります。

もっと簡単な例は、ポインタへのポインタの代わりにポインタだけを見ることです。単純な階層(公開、非あいまいなど)では、Derived*Base*にキャストしても安全です。何も問題はないので、キャストを書く必要はありません。ただし、Base*Derived*にキャストすることは必ずしも安全ではありません。Derived*がない可能性があります。しかし、それはない安全な - そのキャストを完全に悪化させることはできません。したがって、安全なキャストは暗黙的ですが、安全でないキャストは明示的でなければなりません。

+0

ありがとう、私はUBの議論を使用することができないので、それを変更するために、本質的にそれほど難しいものではないと主張する必要があります。 – evan

+0

@evan Huh?何が変わったのか? – Barry

+0

は標準ではありません。最近私が作業を開始したコード。 – evan

関連する問題