I am trying to design a pipeline for my project. I am loosely relying on the VTK pipeline concept. However, there are major differences.
In my design the input-output connection type matching was done using variadic templates and recursive inheritance (similar to CRTP). This allows me to manually define which segments can be connected with which segments by passing a list of abstract base classes to the base filter/mapper classes. In itself, this does not cause any problems.
I need to be able to work with custom (not necessarily std
/primitive) data types. The VTK pipeline, passes pointers to objects that derive from one of the VTK classes (vtkAlgorithmObject
) through pipeline segments. This allows quite a natural implementation of the pipeline input/output interface with multiple connections. This is where my problem lies.
The VTK implementation of the output port function is:
vtkAlgorithmOutput* vtkAlgorithm::GetOutputPort (int index)
Unfortunately, I cannot return a custom class from the output port. Somehow, I need to have a single (possibly overloaded) function getOutputPort
that will return a different type based on the pre-defined index.
One way of doing this is using a combination of template arguments and overloading:
template<int N>
void getOutputPort(int& i)
{
if (N == 0)
i = 10;
else if (N == 2)
i = 20;
else
throw "Invalid template argument for the return type.";
}
template<int N>
void getOutputPort(string& str)
{
if (N == 1)
str = "qwerty";
else
throw "Invalid template argument for the return type.";
}
However, apart from the obvious problem of splitting the definition and index selection over multiple functions, I have to return by reference, which is not something that I would prefer to do. At the concept, I would like to pass the objects via std::unique_ptr
. This will ensure that two segments downstream the pipeline will never make attempts to use the same resource.
Thus, I am trying to do something similar to what is shown in the code below
template<int N>
auto getOutputPort2()
{
if (N == 0)
return std::unique_ptr<int>(new int(10));
else if (N == 1)
return std::unique_ptr<string>(new string("qwerty"));
else if (N == 2)
return std::unique_ptr<int>(new int(20));
else
throw "Invalid template argument.";
}
For obvious reasons, this results in the error 'inconsistent deduction for auto'. Are there any ways around the problem (not necessarily using auto
)?