For starters: MSVC 6, win2k.
The code below has been cut down and edited to make it a bit more readable, so doesn't exactly match the code I have but hopefully it illustrates the problem.
I have a class that includes a templated member function something like this:
class Manager
{
public:
Manager();
~Manager();
bool Create() { if( m_data==NULL ) { m_data = new List<BaseClass>; } return true; }
template<class param> BaseClass* Construct( char* file_path );
private:
static List<BaseClass>* m_data; // list of data items
};
Manager.cpp
...
List<BaseClass>* Manager::m_data = NULL;
...
// This function fulfills requests for resources.
// It first checks to see if the resource already exists and if
// it doesn't find it, creates the resource and adds it the master list.
template<class param> BaseClass* Manager::Construct( char* file_path )
{
param local_param;
BaseClass* item = NULL;
while( m_data )
{
item = (*m_data);
if( local_param.Type()==item->Type() )
{
// further compares to verify exact match
{
// return the item if it is an exact match
return item;
}
}
m_data++;
}
// item not found so construct from the given path
param* new_item = new param;
new_item->Create( file_path );
item = dynamic_cast<BaseClass*>(new_item);
// add to master list
m_data.Add( item );
return item;
}
BaseClass is the abstract base class for a particular hierarchy of objects within the system:
BaseClass
|____________ChildClass1
|____________ChildClass2
|____________ChildClass3
|
and so on.
This manager class is then intended to be use like so:
...
BaseClass* c1_item = NULL;
Manager manager;
manager.Create();
c1_item = manager.Construct<ChildClass1>( file_path );
...
The idea is that the function takes a template parameter of the particular type of child class that has been requested by the resource system. This it allows it to select only entries of matching type from the master list and so reduce the number of string compares in trying to find if the resource already exists in the requested format.
The actual manager class compiles fine, but I haven't been able to get the syntax for the Construct function correct yet. If I try it as above I get:
error C2275: 'ChildClass1' : illegal use of this type as an expression
see declaration of 'ChildClass1'
or this:
c1_item = manager.Construct( file_path );
gives:
error C2783: 'class BaseClass *__thiscall Manager::Construct(char *)' : could not deduce template argument for 'param'
The template parameter cannot be deduced because it is neither used as a function call parameter or as a return type. Is there any way to instantiate the function call that will tell the compiler what template parameter I want (as with instantiating an instance of a normal template class), or do I have to include the template parameter as an argument to the function call? I've got a few ideas about other ways I could do this and may have to fall back on, but is there anyway to get this working as it is?
Sorry about any duff formatting, but after my first edit it seemed to loose some of the 'source' tags which has made rather a mess. Hopefully its fixed now, but repeated editing may make it worse
.
[edited by - paulc on January 18, 2003 5:49:51 PM]
[edited by - paulc on January 18, 2003 5:53:37 PM]