views:

523

answers:

4

I need to be able to pass a typename as a parameter:

int X = FileRead(file, 9, char);

The concept is for FileRead(std::fstream, int pos, ???) to read pos*sizeof(whatever the type is) to get the desired position. I tried templates:

template<typename T>
T FileRead(std::fstream file, int pos, T type)
{
    T data;
    file.read(reinterpret_cast<char*>(&data), sizeof(data));
    return data;
}

but that required that I create a variable of the type to use every time I wanted to use FileRead, and I really don't feel like redesigning an entire program just because of one function, so is there anyway to use a typename as a parameter?

A: 

There is no such things as types once your program is compiled. This is the style of C++.

Daniel A. White
+8  A: 

To use the name of a type as a parameter, use a template.

template<typename T>
T FileRead(std::fstream &file, int pos)
{
    T data;
    file.read(reinterpret_cast<char*>(&data), sizeof(T));
    return data;
}

This assumes that the type is default constructible. If it is not, I guess you would have difficulty streaming it out of a file anyway.

Call it like this:

char value=FileRead<char>(file, pos);

If you do not want to have to specify the type in the call, you could modify your API:

template<typename T>
void FileRead(std::fstream &file, int pos, T &data)
{
    file.read(reinterpret_cast<char*>(&data), sizeof(T));
}

Then call it like this - the type is inferred:

char value;
FileRead(file, pos, value);
1800 INFORMATION
Then I get the error "could not deduce argument for 'T'"
Keand64
I think you'd need T as an argument rather than just as the return value.
Dan Olson
Call it like FileRead<char>(file, pos);
sth
You will have to call it with the template argument.http://www.codersource.net/cpp_function_template_overloading.html
Daniel A. White
For readability you might want to add 'void' as the return type from FileRead().
JSBangs
Opps heh. Not just readability, if you leave it off then the type defaults to int
1800 INFORMATION
I think in this case, types that are *not* default constructible couldn't be passed anyway (in c++03, at least), since for those, they are not PODs anyway and using read on them would be UB (and "const T" can't be modified either). If your compiler can do that as an extension and you would like to use non-default constructible types, you can use this definition instead: template<typename T> T FileRead(std::fstream return data; }, which is the same technique also used by C::resize standard container functions.
Johannes Schaub - litb
+2  A: 

Very simple:

template<typename T>
T FileRead(std::fstream file, int pos)
{
    T data;
    file.read(reinterpret_cast<char*>(&data), sizeof(data));
    return data;
}

and call it via:

char x = FileRead<char>(file, pos);
rstevens
A: 

Seems like what you really want to do is pass the size of what you think a character is as a parameter, e.g.:

FileRead(file, 9, sizeof(char));
FileRead(file, 3, sizeof(WCHAR)); // or whatever your platform likes.

You can use RTTI to get the typename, e.g.: typeid(*ptr).name(), but you can't call sizeof() on it. And RTTI is icky.

jeffamaphone