Search code examples
c++templatesboostshared-ptrfactory

Compilation error when creating template & boost::shared_ptr based generic factory


I am using c++98 unfortunately.

template <class bT>
class Creator
{
public:
   virtual bT* create()  = 0;
};

template <class bT>
struct CreatorPtr
{
    typedef boost::shared_ptr< Creator<bT> > ptr;
};

template <class bT, class cT>
class CreatorImpl : public Creator<bT>
{
public:
   virtual bT* create() { return new cT; }
};

template <class bT>
class Factory
{
public:
    virtual bT* create(const std::string& name) = 0;
    virtual ~Factory() { _table_creator.clear(); }
protected:
    Factory() {}
    Factory(const Factory&) {}
    Factory &operator=(const Factory&) { return *this; }
    void registerCreator(const std::string& name, typename CreatorPtr<bT>::ptr creator)
        { _table_creator[name] = creator; }
    typedef std::map<std::string, typename CreatorPtr<bT>::ptr> tableCreator;
    typedef typename tableCreator::const_iterator citerTc;
    ......
protected:
    tableCreator _table_creator;
};

I got error

"error: expected nested-name-specifier before ‘tableCreator’" on the "typedef typename tableCreator::const_iterator citerTc;" line. I am using 4.1.2 g++."

Sorry for everyone, I missed typename here "pointed by syam" and deleted the template in the definition of citerTc. Now the code compiles and runs good. Thank you everyone for your help.


Solution

  • Since you have a qualified, dependent type name, you need to use the typename disambiguator to tell the compiler to interpret what comes after the :: as the name of a type (rather than a data member):

        typename CreatorPtr<bT>::ptr // ptr is the name of a type, so you need
    //  ^^^^^^^^                     // to use the "typename" keyword in order
                                     // to let the compiler parse it correctly
    

    So for instance:

    void registerCreator(const std::string& name,
                         typename CreatorPtr<bT>::ptr creator)
    //                   ^^^^^^^^
    

    Similarly:

    typedef std::map<std::string, typename CreatorPtr<bT>::ptr> tableCreator;
    //                            ^^^^^^^^