2011-01-12 2 views
1

Хотя было много строк, написанных на тему reinterpret_cast, и насколько это плохо, я все еще озадачен лучшим способом избежать этого, особенно когда речь идет о таких функциях, как читать и писать из fstream. Итак, вот моя дилемма ...Правильное литье для функций чтения и записи fstream

Предположим, у нас есть целочисленный массив, который мы хотим заполнить некоторыми данными из файла.

std::ifstream iFile(...); 

// presume that the type of this array is not a matter of choice 
int *a = new int[ 100 ]; 

Мы можем читать с несколькими различными слепков:

iFile.read((char *)a, sizeof(int) * 100); 
iFile.read(reinterpret_cast< char * >(a), sizeof(int) * 100); 
iFile.read(static_cast< char * >(static_cast< void * >((a)), sizeof(int) * 100); 

Первый (C-стиль) является устаревшим и новый стиль проливает мы введены в C++ по уважительным причинам. Второй - неспособен и не дает никаких гарантий. Третье утомительно писать и портить удовольствие.

Есть ли альтернатива этому и как мне это сделать?

EDIT:

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

+2

Третий запатентован. Я не понимаю, почему вы не можете использовать reinterpret_cast. Но что именно вы подразумеваете под «unportable и не предлагает никаких гарантий»? Вы имеете в виду утверждение и возможные будущие изменения размера int? –

+1

Хотя технически поведение 'reinterpret_cast' не гарантируется, этот случай - именно то, для чего вы должны его использовать. Большинство реализаций практически не имеют разницы между приложением C-стиля и 'reinterpret_cast'. –

+1

Поведение reinterpret_cast не может быть определено. Но Spec также говорит, что * предназначен для неудивительных для тех, кто знает структуру адресации лежащей в основе машины. * Так что, предполагая, что вы знаете свою машину (стандартный ПК), она должна работать нормально. –

ответ

3

Почему вы не объявлять a, как char* вместо этого, как это:

//int *a = new int[100]; 
char *a = new char[100]; 
iFile.read(a, 100); 

Нет литья теперь требуется.


EDIT:

Хорошо, я прочитал ваш комментарий и комментировал строку в вашем посте. В этом случае:

iFile.read(reinterpret_cast<char*>(a), sizeof(int)*100); 

должно быть достаточно.

Однако, лично я бы выбрал C-стиль ролях:

iFile.read((char*)a, sizeof(int)*100); 

То есть, потому что я не вижу никакой опасности здесь. Все кажется прекрасным даже при использовании C-Style!


Best еще менее утомительным литые

Определите эту функцию шаблона:

template<class To, class From> 
To any_cast(From v) 
{ 
    return static_cast<To>(static_cast<void*>(v)); 
} 

Затем использовать его:

//`From` type will be inferred from the function argument. :-) 
iFile.read(any_cast<char*>(a), sizeof(int)*100); 

Выглядит хорошо?

Я думаю, что этот any_cast можно использовать для литья любого типа в любой тип!

+0

Давайте просто скажем, что у меня нет выбора. Комментарий выше этой строки, должно быть, пропустил вас. – LavaScornedOven

+0

Вы не можете static_cast использовать int * для char *. –

+0

@PigBen: oops .. я имел в виду 'reinterpret_cast' ... исправил его! – Nawaz