Archived

This topic is now archived and is closed to further replies.

kamrann

Function template question

Recommended Posts

Heres my code.
  
template<class T>
void	ReadData(std::ifstream& file, T& t)
{
	file.read((char*)&t, sizeof(T));
}

template<class T>
void	ReadData(std::ifstream& file, std::vector<T>& v)
{
	file.read((char*)&v[0], sizeof(T) * v.size());
}
  
What I want to do is have the function behave differently if the argument is of type std::vector (of any type). A get the error: "none of 2 overloads has best conversion" when I call the function like this: vector v; v.resize(1); ReadData(file, v); Anyone know how I can do this? Cameron

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
try:


  
template< class T >
void ReadData(std::ifstream& file, T& t)
{
file.read((char*)&t, sizeof(T));
}

template< class T, class D >
void ReadData< vector<D> >(std::ifstream& file, std::vector<D>& v)
{
file.read((char*)&v[0], sizeof(T) * v.size());
}


NOTE: you *need* the extra space after vector<D>, or else the compiler will think you''re using operator >>

Share this post


Link to post
Share on other sites
I tried it. It compiled ok, but executed the normal (first) version of the function.
There seems something weird with your code though. You make the vector of type D (vector) - in this case it should be
sizeof(D) in the implementation, not sizeof(T). But then the T template argument wouldn''t be used.

Any other ideas?

Cameron

Share this post


Link to post
Share on other sites
The problem is that passing an std::vector type will fit into either function, so the compiler doesn''t know which one to use. It''s the same as defining two functions that have the same name and take the same arguments.

You can probably do just the first function and use the RTTI calls (typeid) to check if you have a vector type or not in an if statement, like so:


  
template< class T >
void ReadData(std::ifstream& file, T& t)
{
if(strstr(typeid(t).name(), "std::vector") != NULL)
{
cerr << "Vector Version" << endl;
}
else
{
cerr << "Normal Version" << endl;
}
}


I did a quick test of this and it appears to work like you want.

Share this post


Link to post
Share on other sites
The way you've set things up here makes explicitly calling the function a bit strange. The way to do it is actually by doing this:

vector<int> v;
ReadData<int>(file,v);

This is because your template definition expects an int for the type of vector. Once you have clarified to the compiler that you are using an integer specialization of the ReadData function, the compiler can decide based on your argument which version to use.

Edit: fixed up tags

[edited by - premandrake on May 2, 2002 2:00:40 PM]

Share this post


Link to post
Share on other sites
Whoops, Sabreman is completely right. GCC handles your code fine and calls the vector version. Chalk my reply to too much time spent with MSVC''s template bugs .

However, it is a valid workaround (although ugly) for getting what you want using MSVC 6.

Share this post


Link to post
Share on other sites