我正在努力思考模板模板如何工作以实现类似的功能,如下所示。
考虑两个类(在 Java 中)。第一个类通过指定只能在其中存储第二个模板参数的对象来限制 pack
方法返回的集合:
abstract class ContainerPacker<T, Container extends Collection<T>> {
abstract Container pack(T t);
}
这个类的实现,比方说,Integer
类型可能如下所示:
class IntegerContainerPacker extends ContainerPacker<Integer, List<Integer>> {
@Override
List<Integer> pack(Integer t) {
List<Integer> list = new ArrayList<>(t);
list.add(t);
return list;
}
}
现在我想使用模板模板在 C++ 中做一些类似的事情。请注意 Container
本身是一个模板:
template <typename T, template <typename U> class Container>
class ContainerPacker {
public:
virtual Container<T> pack(T) = 0;
};
不过我在实现它时遇到了问题。以下代码无法编译:
class IntegerVectorPacker : public ContainerPacker<int, std::vector> {
public:
std::vector<int> pack(int t) {
std::vector<int> v = std::vector<int>();
v.push_back(t);
return v;
}
};
错误是:
error: type/value mismatch at argument 2 in template parameter list for ‘template class Container> class ContainerPacker’ class IntegerVectorPacker : public ContainerPacker {
和
note: expected a template of type ‘template class Container’, got ‘template class std::vector’
我一直在寻找答案,但甚至很难弄清楚该问什么问题。模板模板很难。
最佳答案
尝试
template <typename T, template <typename...> class Container>
您代码中的问题(一个问题?)是 std::vector
是一个模板类,它接收多个模板参数(两个:第二个有默认类型);所以不匹配Container
.
定义 Container
因为接收零个或多个模板应该允许与 std::vector<int>
匹配(实际上是 std::vector<int, std::allocator<int>>
)和其他容器。
-- 编辑 --
我现在看到你用 C++ 标记了这个问题,而不是 C++11(或更新版本)。
typename...
建议仅从 C++11 开始有效,因为可变参数模板以前不可用。
对于C++98你可以这样写
template <typename T, template <typename, typename> class Container>
但这只适用于两个参数容器。
-- 编辑 2 --
离题建议。
如果您可以使用 C++11 或更新版本(因此可变参数模板)切换 Container
的顺序和 T
对于 ContainerPacker
并转换 T
是可变参数包;像
template <template <typename...> class Container, typename ... Ts>
class ContainerPacker {
public:
virtual Container<Ts...> pack(Ts...) = 0;
};
它更加灵活。
关于c++ - 接受另一个模板参数的模板模板集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47538499/