Скажем, что я хочу отбрасывать A*
в char*
и наоборот, у нас есть два варианта (я имею в виду, что многие из нас думают, что у нас есть два выбора, потому что оба, похоже, работают! Следовательно, путаница!):
struct A
{
int age;
char name[128];
};
A a;
char *buffer = static_cast<char*>(static_cast<void*>(&a)); //choice 1
char *buffer = reinterpret_cast<char*>(&a); //choice 2
Оба работают нормально.
//convert back
A *pA = static_cast<A*>(static_cast<void*>(buffer)); //choice 1
A *pA = reinterpret_cast<A*>(buffer); //choice 2
Даже это прекрасно работает!
Итак, почему мы имеем reinterpret_cast
в С++, когда две цепочки static_cast
могут выполнять свою работу?
Некоторые из вас могут подумать, что эта тема дублирует предыдущие темы, такие как перечисленные внизу этого сообщения, но это не так. Эти темы обсуждаются только теоретически, , но ни один из них не дает даже одного примера, демонстрирующего, почему reintepret_cast
действительно нужен, а два static_cast
будет уверенно сбой. Я согласен, один static_cast потерпит неудачу. Но как насчет двух?
Если синтаксис двух прикованных static_cast
выглядит громоздким, тогда мы можем написать шаблон функции, чтобы сделать его более удобным для программистов:
template<class To, class From>
To any_cast(From v)
{
return static_cast<To>(static_cast<void*>(v));
}
И тогда мы можем использовать это, как:
char *buffer = any_cast<char*>(&a); //choice 1
char *buffer = reinterpret_cast<char*>(&a); //choice 2
//convert back
A *pA = any_cast<A*>(buffer); //choice 1
A *pA = reinterpret_cast<A*>(buffer); //choice 2
Также см. эту ситуацию, когда any_cast
может быть полезна: Правильное кастинг для функций чтения и записи fstream.
Итак, мой вопрос в основном,
- Почему у нас есть
reinterpret_cast
в С++? - Пожалуйста, покажите мне хотя бы один пример, где два прикованных
static_cast
наверняка не смогут выполнить одну и ту же работу?