Reputation: 397
I have a family of classes for which I want to write an abstract factory. The minimal example below will give you the general idea.
My problem is that I can't figure out how to define member functions of ConcreteFactory >. clang++ reports this error:
template-class-of-template-class.cc:36:39: error: nested name specifier 'ConcreteFactory<Derived<NUM> >::' for
declaration does not refer into a class, class template or class template partial specialization
Base* ConcreteFactory<Derived<NUM> >::construct() const
I've only been able to define them for fully specified classes, e.g. ConcreteFactory >. There will be an awful lot of duplicated code if I have to do it that way. Is there any way to avoid writing this boilerplate through intelligent use of templates?
#include <cstdlib>
class Base
{
};
template <typename NUM>
class Derived : public Base
{
public:
Derived(NUM const &thing) : m_thing(thing) {}
~Derived() {}
private:
NUM m_thing;
};
class AbstractFactory
{
public:
virtual Base *construct() const = 0;
};
template <class Y>
class ConcreteFactory
{
public:
Base* construct() const
{
return new Y();
}
};
template <typename NUM>
template <>
Base* ConcreteFactory<Derived<NUM> >::construct() const
{
return new Derived<NUM>(rand());
}
int main(int argc, char *argv[])
{
ConcreteFactory<Base> baseFact;
ConcreteFactory<Derived<int> > intFact;
ConcreteFactory<Derived<double> > doubleFact;
Base* a = baseFact.construct();
Base* b = intFact.construct();
Base* c = doubleFact.construct();
delete c;
delete b;
delete a;
}
Upvotes: 0
Views: 41
Reputation: 42899
You can't partially specialize on a member function of a template class.
You have to partially specialize the whole template class.
See corrected code below:
// partial specialization of class `ConcreteFactory`
template<typename NUM>
class ConcreteFactory<Derived<NUM>> {
public:
Base* construct() const { return new Derived<NUM>(rand());}
};
see Display.
Upvotes: 1