11

CodeProject でいくつかのコードを調べていて、C++ キャスト用の次のコードに出くわしました。

template <class OutputClass, class InputClass>
union horrible_union{
    OutputClass out;
    InputClass in;
};
template <class OutputClass, class InputClass>
inline OutputClass horrible_cast(const InputClass input){
    horrible_union<OutputClass, InputClass> u;
    u.in = input;
    return u.out;
}

キャストが上記の方法で実装されるのはなぜですか。手動キャストを行うことができないのはなぜですか。通常のキャストが機能しない場合の例を誰かが挙げることができますか?

4

2 に答える 2

9

このアプローチでは、未定義の動作に依存していますが、基本的にどのキャストでも問題なく使用できます。

関係のない型の間でキャストすると、通常のキャストは文句を言いますが、これはそうではありません。

struct A{};
struct B{};

template <class OutputClass, class InputClass>
union horrible_union{
    OutputClass out;
    InputClass in;
};
template <class OutputClass, class InputClass>
inline OutputClass horrible_cast(const InputClass input){
    horrible_union<OutputClass, InputClass> u;
    u.in = input;
    return u.out;
}

int main()
{
    A a;
    B b;
    a = horrible_cast<A,B>(b);   //this compiles
    a = reinterpret_cast<A>(b);  //this doesn't
} 

結論:それは恐ろしいことです、やらないでください。

于 2012-11-11T19:53:01.453 に答える
2

このように共用体を使用することは、一般にハードreinterpret_castポインターとほぼ同等です。ただし、それはオブジェクトをコピーしません。あなたの例はコピーします(実際、RVOでも2回。引数として持つ方がむしろ効率的const InputClass& inputです)。したがって、元のオブジェクトを変更することなく、その結果を直接操作できます。

これはいったい何の役に立つのだろう…うーん。本当に良いユースケースはないと思います。チェックされていないキャストは常に避けるべきです.David Hammenが指摘したように、これは実際には完全に定義されていません(ただし、「正しく」使用されれば通常は機能します)。

于 2012-11-11T19:54:37.157 に答える