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.
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;
// ^^^^^^^^