Although there was a lot of lines written on the topic of reinterpret_cast, and how bad it is, I'm still puzzled with best way to avoid it, especially when dealing with functions like read and write from fstream. So, here is my dilemma...
Let's say we have an integer array that we want to fill with some data from a file.
std::ifstream iFile( ... );
// presume that the type of this array is not a matter of choice
int *a = new int[ 100 ];
We can read with a few different casts:
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 );
The first one (C-style) is outdated and new style casts we're introduced in C++ for good reasons. The second one is unportable and offers no guarantees. The third one is tedious to write and spoils the fun.
Is there any alternative to this and how should I go about it?
EDIT:
The goal is to achieve code as portable and as standard-conforming as possible.
fstream Library: Fstream is a library that consists of both, ofstream and ifstream which means it can create files, write information to files, and read information from files. This header file is generally used as a data type that represents the file stream.
reinterpret_cast is a type of casting operator used in C++. It is used to convert a pointer of some data type into a pointer of another data type, even if the data types before and after conversion are different.
ifstream is input file stream which allows you to read the contents of a file. ofstream is output file stream which allows you to write contents to a file. fstream allows both reading from and writing to files by default.
An iostream is a stream which you can write to and read from, you probably won't be using them much on their own. An fstream is an iostream which writes to and reads from a file. So: every fstream is an iostream but not every iostream is an fstream.
Why don't you declare a
as char*
instead, like this:
//int *a = new int[100];
char *a = new char[100];
iFile.read(a, 100 );
No casting required now.
EDIT:
Okay, I read your comment and the commented line in your post. In that case:
iFile.read(reinterpret_cast<char*>(a), sizeof(int)*100);
should suffice.
However,I personally would choose C-style cast:
iFile.read((char*)a, sizeof(int)*100);
That is because I don't see any danger here. Everything seems fine even with C-Style cast!
Define this function template:
template<class To, class From>
To any_cast(From v)
{
return static_cast<To>(static_cast<void*>(v));
}
Then use it:
//`From` type will be inferred from the function argument. :-)
iFile.read(any_cast<char*>(a), sizeof(int)*100);
Looks good?
I think this any_cast
can be used to cast from any-type to any-type!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With