I'm currently trying to program a pipeline, which is able to process different kind of data in every pipeline element. Now I want to use unique_ptr
s with some kind of template polymorphism and template specialization.
struct Start {}; // Dummy struct
template<typename In, typename Out>
class PipelineElement {
public:
virtual Out process(In in) = 0;
};
// partial template specialization for the first pipeline element
template<typename Out>
class PipelineElement<Start, Out> {
public:
virtual Out process() = 0;
};
class Producer : public PipelineElement<Start, int> {
int process() override { ... }
};
Now a function shall take a unique_ptr
of a partial specialized PipelineElement
. However, the following won't compile with the error message:
auto Pipeline::setStart<int>(std::unique_ptr<PipelineElement<Start,int>,std::default_delete<PipelineElement<Start,int>>>)': cannot convert argument 1 from 'std::unique_ptr<Producer,std::default_delete<Producer>>' to 'std::unique_ptr<PipelineElement<Start,int>,std::default_delete<PipelineElement<Start,int>>>
class Pipeline {
template<typename Out>
static auto setStart(std::unique_ptr<PipelineElement<Start, Out>> element) { ... }
};
int main() {
Pipeline::setStart(std::make_unique<Producer>());
}
If I use regular pointers instead, it does compile without any errors.
Why does the version with normal pointers compile, and the version with smart pointers doesn't?
class Pipeline {
template<typename Out>
auto setStart(PipelineElement<Start, Out>* element) { ... }
};
int main() {
Pipeline::setStart(new Producer());
}