Скажем, я хочу привести 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
в C ++, когда с двумя цепями 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
в C ++?
- Пожалуйста, покажите мне хотя бы один пример, где с двумя цепями
static_cast
наверняка не выполнит ту же работу?