我正在尝试为我的项目设计管道。我松散地依赖于 VTK 管道概念。但是,存在重大差异。
在我的设计中,输入输出连接类型匹配是使用可变参数模板和递归继承(类似于 CRTP)完成的。这允许我通过将抽象基类列表传递给基本过滤器/映射器类来手动定义哪些段可以与哪些段连接。这本身不会造成任何问题。
我需要能够使用自定义(不一定是 std
/primitive)数据类型。 VTK 管道通过管道段传递指向从 VTK 类之一 (vtkAlgorithmObject
) 派生的对象的指针。这允许非常自然地实现具有多个连接的管道输入/输出接口(interface)。这就是我的问题所在。
输出端口函数的VTK实现是:
vtkAlgorithmOutput* vtkAlgorithm::GetOutputPort (int index)
不幸的是,我无法从输出端口返回自定义类。不知何故,我需要一个(可能重载的)函数 getOutputPort
,它将根据预定义的索引返回不同的类型。
这样做的一种方法是结合使用模板参数和重载:
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.";
}
但是,除了在多个函数上拆分定义和索引选择的明显问题外,我还必须通过引用返回,这不是我愿意做的事情。在概念上,我想通过 std::unique_ptr
传递对象。这将确保管道下游的两个部分永远不会尝试使用相同的资源。
因此,我正在尝试做类似于下面代码中所示的事情
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.";
}
由于显而易见的原因,这会导致错误“自动扣减不一致”。是否有解决该问题的方法(不一定使用 auto
)?
最佳答案
你可以这样做:
template<int N> struct helper_type {
static_assert(N == 0 || N == 1 || N == 2, "Unexpected value");
using type = typename std::conditional<N == 1,
std::unique_ptr<std::string>,
std::unique_ptr<int>>::type;
};
/* only specializations are valid */
template<int N>
typename helper_type<N>::type getOutputPort2() = delete;
template<>
typename helper_type<0>::type getOutputPort2<0>()
{
return std::unique_ptr<int>(new int(10));
}
template<>
typename helper_type<1>::type getOutputPort2<1>()
{
return std::unique_ptr<std::string>(new std::string("asdf"));
}
template<>
typename helper_type<2>::type getOutputPort2<2>()
{
return std::unique_ptr<int>(new int(20));
}
关于具有多个输出端口的 C++ 管道段 - 类型匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27627908/