| | |
How do I work around this? - virtual templates
Please support our C++ advertiser: Intel Parallel Studio Home
![]() |
Hopefully I'll be able to explain this issue. If not, I may just have to post a lot of code. Basically, I've got a base class called 'Log' with virtual methods of writing to a log. I have two descendent classes - ScreenLog and FileLog (with all the same methods). (These methods include writing a std::string to a log, writing a char, a float, a vr_arg, a vector, a list .etc.).
I then have a class called MultiLog (which does not descend from Log), which holds a vector of 'Log *' . When I call writeLog on MultiLog, it iterates through each of the Log * objects inside the vector (which are really ScreenLog and FileLog objects), and calls the respective writeLog function.
My problem is this:
I have 2 functions in both FileLog and ScreenLog, that are templated. They basically call a function in another class that I wrote that will iterate through a vector or list of any type and return a string. This allows me to easily log a vector or list of any kind.
template <class Generic> void writeLog(vector<Generic> & logVector )
{
writeLog ( General::vectorToString( logVector ));
}
template <class Generic> void writeLog(list<Generic> & logList )
{
writeLog ( General::listToString( logList ));
}
The problem is that on Visual studio .net, I am required to add functions on the Log class, otherwise they won't work for MultiLog because it's the Log * that I'm using. however, because the functions are templated, I am unable to create the virtual functions (it complains that template and virtual don't mix). If I don't make them virtual, then instead of calling the appropriate ScreenLog or FileLog functions, it calls the Log one, which doesn't do anything.
The weird thing is, on Sun Studio compiler (solaris), I'm not required to create the functions at all for the Log class, and everything works as designed. (I suspect I'm 'getting lucky' that Sun Studio is letting me get away with something illegal)
Anybody have any ideas on how to make this code work on both compilers?
I then have a class called MultiLog (which does not descend from Log), which holds a vector of 'Log *' . When I call writeLog on MultiLog, it iterates through each of the Log * objects inside the vector (which are really ScreenLog and FileLog objects), and calls the respective writeLog function.
My problem is this:
I have 2 functions in both FileLog and ScreenLog, that are templated. They basically call a function in another class that I wrote that will iterate through a vector or list of any type and return a string. This allows me to easily log a vector or list of any kind.
template <class Generic> void writeLog(vector<Generic> & logVector )
{
writeLog ( General::vectorToString( logVector ));
}
template <class Generic> void writeLog(list<Generic> & logList )
{
writeLog ( General::listToString( logList ));
}
The problem is that on Visual studio .net, I am required to add functions on the Log class, otherwise they won't work for MultiLog because it's the Log * that I'm using. however, because the functions are templated, I am unable to create the virtual functions (it complains that template and virtual don't mix). If I don't make them virtual, then instead of calling the appropriate ScreenLog or FileLog functions, it calls the Log one, which doesn't do anything.
The weird thing is, on Sun Studio compiler (solaris), I'm not required to create the functions at all for the Log class, and everything works as designed. (I suspect I'm 'getting lucky' that Sun Studio is letting me get away with something illegal)
Anybody have any ideas on how to make this code work on both compilers?
>I am required to add functions on the Log class
If you want them to be treated polymorphically, yes. But templates can't be virtual, and writeLog is best written as a template. Annoying little impasse, isn't it?
Whatever will you do? How about moving the template up a level, to a template class at Log and MultiLog instead of template functions within Log? Then you can make writeLog virtual and still have the template parameter Generic from the class template to work with. This offers both the behavioral polymorphism of virtual functions and the type polymorphism of templates.
If you want them to be treated polymorphically, yes. But templates can't be virtual, and writeLog is best written as a template. Annoying little impasse, isn't it?
Whatever will you do? How about moving the template up a level, to a template class at Log and MultiLog instead of template functions within Log? Then you can make writeLog virtual and still have the template parameter Generic from the class template to work with. This offers both the behavioral polymorphism of virtual functions and the type polymorphism of templates. I'm here to prove you wrong.
Doesn't that require Log to be explicitly declared as handling a specific type of data when instantiated? (something I don't want to do).
I was able to get around the issue by having multiLog call the General::vectorToString function and then call the existing
writeLog( std::string) function of the ScreenLog and FileLog instead of calling the writeLog( vector<Generic> ...) functions of ScreenLog and FileLog
(Basically, Log now longer requires the template functions...)
I was able to get around the issue by having multiLog call the General::vectorToString function and then call the existing
writeLog( std::string) function of the ScreenLog and FileLog instead of calling the writeLog( vector<Generic> ...) functions of ScreenLog and FileLog
(Basically, Log now longer requires the template functions...)
•
•
Join Date: Jul 2005
Posts: 164
Reputation:
Solved Threads: 5
template member functions may not be virtual but often you can get around this by templating a class rather than a member function. The only reason you cant have template member functions is because the compiler would never be able to know the vtable size.
>Doesn't that require Log to be explicitly declared as handling a
>specific type of data when instantiated? (something I don't want to do).
Yes. At this point you choose the lesser of two evils. You can't do what you want because the language is defined not to allow it. You can get around it by using a slightly less convenient syntax at the class level. Is there a legitimate reason for not wanting to use a type instantiation of a template class?
>specific type of data when instantiated? (something I don't want to do).
Yes. At this point you choose the lesser of two evils. You can't do what you want because the language is defined not to allow it. You can get around it by using a slightly less convenient syntax at the class level. Is there a legitimate reason for not wanting to use a type instantiation of a template class?
I'm here to prove you wrong.
>Be gentle.
Okay. Both your code and your design are pretty fugly. I kept having traumatic flashbacks to early Java while reading your code. But, I can now see why you're doing what you're doing with the way you backed yourself into a corner like that.
What were you planning on using this program for?
Okay. Both your code and your design are pretty fugly. I kept having traumatic flashbacks to early Java while reading your code. But, I can now see why you're doing what you're doing with the way you backed yourself into a corner like that.
What were you planning on using this program for? I'm here to prove you wrong.
![]() |
Other Threads in the C++ Forum
- Previous Thread: Just Small Help
- Next Thread: Need help in C/C++
| Thread Tools | Search this Thread |
api array based beginner binary bitmap c++ c/c++ calculator char char* class classes coding compile compiler console conversion count database delete deploy desktop developer directshow dll dynamiccharacterarray email encryption error file forms fstream function functions game getline givemetehcodez google graph homeworkhelp homeworkhelper iamthwee ifstream input int integer lib linkedlist linux list loop looping loops map math matrix memory multiple news node number numbertoword output parameter pointer problem program programming project proxy python random read recursion recursive reference return rpg sorting string strings struct template templates text tree unix url variable vector video visual visualstudio win32 windows winsock word wordfrequency wxwidgets






