I am just learning how to work with template template parameters and am having trouble invoking a function.
Compiler Error: candidate template ignored: invalid explicitly-specified argument for template parameter 'Container'
My purpose in using the template template approach is to have a very generic composite class that can handle any container type.
For illustration purposes, I am working with Shapes. So I have a ShapeComposite, PolyLine, and a ShapeFactory.
PolyLine extends ShapeComposite and ShapeComposite is where the generic container will live. Can you please help me understand why I am running into this compiler error?
Shape.hpp
class Shape
{
public:
// just an abstract interface for concrete shapes
};
ShapeComposite.hpp
template<typename T,template<typename S, typename Alloc> class Container, typename TAlloc = std::allocator<T>>
class ShapeComposite : public Shape
{
private:
Container<T, TAlloc> shapes;
public:
ShapeComposite();
~ShapeComposite() override = default;
void addShape(const std::shared_ptr<Shape>& shape);
ShapeComposite.cpp
template<typename T, template<typename S, typename Alloc> class Container, typename TAlloc>
ShapeComposite<T, Container, TAlloc>::ShapeComposite() : shapes{}
{
// default ctor
}
template<typename T, template<typename S, typename Alloc> class Container, typename TAlloc>
void ShapeComposite<T, Container, TAlloc>::addShape(const std::shared_ptr<Shape>& shape)
{
shapes.push_back(shape);
}
PolyLine.hpp
template<typename T, template<typename S, typename Alloc> class Container, typename TAlloc = std::allocator<T>>
class PolyLine : ShapeComposite<T, Container, TAlloc>
{
public:
PolyLine();
~PolyLine() override = default;
};
PolyLine.cpp
template<typename T, template<typename S, typename Alloc> class Container, typename TAlloc>
PolyLine<T, Container, TAlloc>::PolyLine() : ShapeComposite<Point, Container, TAlloc>()
{
// default ctor
}
ShapeFactory.hpp
class ShapeFactory
{
public:
ShapeFactory() = default;
virtual ~ShapeFactory() = default;
virtual Point createStartPoint();
virtual Point createEndPoint();
virtual Line createLine() final;
virtual Point createPoint() = 0;
template<typename T = Point, template<typename S, typename Alloc>
class Container, typename TAlloc = std::allocator<T>>
PolyLine<T, Container> createPolyLine();
};
ShapeFactory.cpp
Point ShapeFactory::createStartPoint()
{
return createPoint();
}
Point ShapeFactory::createEndPoint()
{
return createPoint();
}
// Template method
Line ShapeFactory::createLine()
{
Point startPoint = createStartPoint();
Point endPoint = createEndPoint();
return Line{startPoint, endPoint};
}
template<typename T, template<typename S, typename Alloc> class Container, typename TAlloc>
PolyLine<T, Container> ShapeFactory::createPolyLine()
{
PolyLine<T, Container> polyLine ;
int numLines = 0;
std::cout << "How many lines would you like to create? ";
std::cin >> numLines;
for (int i = 0; i < numLines; ++i)
{
Line line = createLine();
polyLine.addShape(line);
}
}
ConsoleShapeFactory (just a concrete factory but creating a PolyLine is implemented in the base class)
class ConsoleShapeFactory : public ShapeFactory
{
public:
ConsoleShapeFactory();
~ConsoleShapeFactory() override = default;
// Function Overrides
Point createPoint() override;
};
Attempt to create a PolyLine via the ShapeFacotry:
int main()
{
ConsoleShapeFactory factory;
factory.createPolyLine<std::list<Point>>()();
}
It seems you're confusing templates and types.
std::listis a (class) template.std::list<Point>is an instantiated class template, and therefore a class, and a type.I can't figure out what you want. Do you want to allow
Factory.createPolyLine<std::list<FooBar::Point>>()();as well? If so, you need to define waht properties a point-like class should have.It also seems you're defining templates in .cpp files. That can't work; the template body has to be available at the point of instantiation. I.e.
Factory.createPolyLine<std::list<Point>>()();requires not just the declaration, but the whole definition ofcreatePolyLine