简体   繁体   中英

C++: Templates - No Matching Function to call

I have an Object Factory Class which has a method called registerCreator as defined below:

template < class Base, class Key, typename ObjectCreator = Base* (*)()>

class ObjectFactory

{

      public:
        bool registerCreator( const Key& id, ObjectCreator creator)
        {
          return associations_.insert( typename IdToObjectMap::value_type(id, creator)).second != 0;
        }
        ...
      private:
        typedef std::map<Key, ObjectCreator> IdToObjectMap;
        IdToObjectMap associations_;

};

This class is wrapped in a singleton Holder which is essentially implemented following the Loki::SingletonHolder.

I have created a typedef to this as:

typedef SingletonHolder < ObjectFactory < AbstractResource, const char*, AbstractResource* (*)()> > ResourceFactory;

AbstractResource is an empty class for now. I have used another ResourceBase class as follows to help with static polymorphism.

template <class DerivedType>
class ResourceBase
{
  public:
    virtual ~ResourceBase();
    static bool registerWithFactory();

  protected:

    ResourceBase();

  private:

    static const bool _Initialized;
};

// this also includes its .C implementation which is as follows:

template <class DerivedType>
const bool ResourceBase<DerivedType>::_Initialized = 
ResourceBase<DerivedType>::registerWithFactory();

template<class DerivedType>
bool ResourceBase<DerivedType>::registerWithFactory()
{
  if (! _Initialized)
  {
    return ResourceFactory::Instance().template registerCreator<DerivedType>    (DerivedType::className() , &DerivedType::allocate);
  }
}

and then my concrete class is as follows: class FileManager : public ResourceBase, AbstractResource { public: FileManager(); ~FileManager() { }

    static const char* className();
    static AbstractResource* allocate();
};

With FileManager implementation as:

const char* FileManager::className()
{
    return "FileManager";
}

AbstractResource* FileManager::allocate()
{
  return new FileManager;
}

on compilation, I am getting:

error: no matching function for call to `ObjectFactory<AbstractResource, const char*, AbstractResource*(*)()>::registerCreator(const char*, AbstractResource*(*)())'

Can anyone please suggest what is the issue here? I am missing something very basic as it appears.

The problem is that you call registerCreator using the syntax to call a template member function of a class:

return ResourceFactory::Instance()
       .template registerCreator<DerivedType>
       (DerivedType::className() , &DerivedType::allocate);

However, registerCreator is a non-template member function of a template class. After the template class is instantiated (which you did, at the ResourceFactory definition), the non-template function does not need any additional specialization to be called. Ie the following may work, as you can see at http://ideone.com/YIytS (courtesy of @ Lol4t0 ).

return ResourceFactory::Instance()
       .registerCreator (DerivedType::className() , &DerivedType::allocate);

template definitions have to be put in the same file as their declaration. Another comment: try to getrid of the typedefs. I just had a.somewhat similar problem and people here managed to rewrite my code without typedefs.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM