C ++: шаблоны - нет подходящей функции для вызова - PullRequest
0 голосов
/ 29 января 2012

У меня есть Object Factory Class, у которого есть метод с именем registerCreator, как определено ниже:

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_;

};

Этот класс заключен в одноэлементный Holder, который по существу реализован после Loki :: SingletonHolder.

Я создал typedef для этого как:

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

AbstractResource - пока пустой класс. Я использовал другой класс ResourceBase, чтобы помочь со статическим полиморфизмом.

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

  protected:

    ResourceBase();

  private:

    static const bool _Initialized;
};

// это также включает его реализацию .C, которая выглядит следующим образом:

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);
  }
}

и тогда мой конкретный класс выглядит следующим образом: Класс FileManager: общедоступный ResourceBase, AbstractResource { общественности: Файловый менеджер(); ~ FileManager () {}

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

С реализацией FileManager как:

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

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

при компиляции я получаю:

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

Может кто-нибудь предложить, в чем здесь проблема? Я скучаю по чему-то очень простому, как кажется.

Ответы [ 2 ]

1 голос
/ 29 января 2012

Проблема в том, что вы вызываете registerCreator, используя синтаксис для вызова функции-члена шаблона класса:

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

Однако registerCreator - это не шаблонная функция-член класса шаблона. После создания экземпляра класса шаблона (что вы и сделали в определении ResourceFactory) функция без шаблона не нуждается в какой-либо дополнительной специализации для вызова. То есть следующее может работать, как вы можете видеть на http://ideone.com/YIytS (любезно предоставлено @ Lol4t0 ).

return ResourceFactory::Instance()
       .registerCreator (DerivedType::className() , &DerivedType::allocate);
0 голосов
/ 29 января 2012

определения шаблона должны быть помещены в тот же файл, что и их объявление.Еще один комментарий: попробуйте получить getrid из typedefs.У меня просто была примерно такая же проблема, и люди смогли переписать мой код без typedefs.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...