Реализация С++ Cast

Я просматривал код CodeProject и набрал следующий код для кастования С++.

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;
}

Почему бросок реализован выше. Почему мы не можем просто сделать ручную трансляцию. Может ли кто-нибудь привести пример того, когда нормальный бросок не будет работать?

Ответ 1

Этот подход в основном позволяет вам уйти от любого актера, хотя он полагается на поведение undefined.

Обычный бросок будет жаловаться при литье между несвязанными типами, тогда как это не будет.

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
} 

Итог: это ужасно, не делайте этого.

Ответ 2

Использование объединения таким образом в общем случае примерно эквивалентно жесткому указателю reinterpret_cast. Тем не менее, это не копирует объекты, ваш пример (на самом деле, дважды даже с RVO), было бы более эффективным иметь const InputClass& input в качестве аргумента). Таким образом, вы можете напрямую работать с его результатом, не изменяя при этом оригинальный объект.

Что именно это полезно для... hm. Я не думаю, что там действительно хороший вариант использования, всегда следует избегать неконтролируемых отбросов, и, как заметил Дэвид Хэммен, это на самом деле полностью undefined (хотя он будет нормально работать, если его использовать "правильно" ).