0

I am trying to implement a simple plugin manager using concepts found in this answer. I am implementing it as a template so that I can instantiate different managers for plugins implementing different interfaces.

However, I can't get it to compile.

Here is an extract which demonstrates the problem:

#include <map>
#include <string>

template<typename InterfaceType>
class PluginManager {

public:
    // Map between plugin name and factory function
    typedef std::map<std::string, InterfaceType*(*)()> map_type;

    static InterfaceType *createInstance(std::string const& plugInName) {
        map_type::iterator iter = map().find(plugInName);
        if (iter == map().end())
            return 0;
        return iter->second();
    }

protected:
    static map_type & map() {
        static map_type map;
        return map;
    }

};

class MyInterface {};

PluginManager<MyInterface> myInterfacePluginManager;

int main(int argc, char *argv[]) {
}

When trying to compile it, this is what happens:

$ g++ pimgr_bug.cpp
pimgr_bug.cpp: In static member function ‘static InterfaceType* PluginManager<InterfaceType>::createInstance(const std::string&)’:
pimgr_bug.cpp:12: error: expected ‘;’ before ‘iter’
pimgr_bug.cpp:13: error: ‘iter’ was not declared in this scope
pimgr_bug.cpp:15: error: ‘iter’ was not declared in this scope

It seems to be related to the definition of map_type: if I change it so that the map value type is some concrete class it compiles fine, but with the value type defined as InterfaceType*(*)() or indeed anything related to InterfaceType at all, then it does not work. The map is supposed to hold a mapping between plugin name and pointer to a corresponding factory function.

I am almost certainly missing some basic understanding of template syntax!

Surely is it possible to create a map within a template which holds a type defined by one of the template arguments?

I am using gcc 4.4.7 and unfortunately cannot use C++11 (if that's relevant).

Thanks!

Community
  • 1
  • 1
harmic
  • 28,606
  • 5
  • 67
  • 91

1 Answers1

0

map_type::iterator is a dependent name, because map_type depends on a template parameter (InterfaceType). Subsequently, the compiler doesn't assume that map_type::iterator names a type unless you explicitly say so*.

Therefore, write

typename map_type::iterator iter = map().find(plugInName);

And it should compile just fine.

* or the name lookup finds one, but that doesn't apply here.

Columbo
  • 60,038
  • 8
  • 155
  • 203