【问题标题】:Template template collection accepting another template argument模板模板集合接受另一个模板参数
【发布时间】:2018-05-12 07:39:13
【问题描述】:

我正试图围绕模板模板如何工作以实现如下所示的类似功能。

考虑两个类(在 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;
    }
};

错误是:

错误:“模板类 Container> 类 ContainerPacker”的模板参数列表中参数 2 的类型/值不匹配 类 IntegerVectorPacker : 公共 ContainerPacker {

注意:需要一个“模板类容器”类型的模板,得到“模板类 std::vector”

我一直在寻找答案,但很难弄清楚要问什么问题。模板模板很难。

【问题讨论】:

  • 您提到的第二个错误似乎与您提供std::vector 作为第二个模板参数这一事实有关,而不是提供std::vector&lt;int&gt; 的完全专业化。这是说它需要一个模板类,但您提供了一个类名。

标签: c++ templates generic-programming


【解决方案1】:

试试

template <typename T, template <typename...> class Container>

您的代码中的问题(问题?)是std::vector 是一个模板类,它接收多个模板参数(第二个:第二个具有默认类型);所以不匹配Container

Container 定义为接收零个或多个模板应该允许与std::vector&lt;int&gt;(实际上是std::vector&lt;int, std::allocator&lt;int&gt;&gt;)和其他容器匹配。

-- 编辑--

我现在看到您已经标记了这个问题 C++ 而不是 C++11(或更高版本)。

typename... 建议仅从 C++11 开始有效,因为以前不提供可变参数模板。

对于 C++98 你可以写

template <typename T, template <typename, typename> class Container>

但这仅适用于两个参数容器。

-- 编辑 2--

离题建议。

如果您可以使用 C++11 或更新版本(因此可变参数模板),则将 ContainerT 的顺序切换为 ContainerPacker 并将 T 转换为可变参数包;像

template <template <typename...> class Container, typename ... Ts>
class ContainerPacker {
  public:
    virtual Container<Ts...> pack(Ts...) = 0;
};

它更加灵活。

【讨论】:

  • 哦,太完美了!我注意到它有多个模板参数,但第二个是默认的,所以我认为可以省略它。无论如何,它有效,谢谢(:
  • @Jezor - 添加了一个离题建议(以防你可以使用 C++11 或更高版本)
  • 再次感谢您(:我使用的是 C++11,实际上,我一直想知道如何在实现中指定其他模板参数
  • 顺便问一下,您是否有任何资源可以从中获得答案,或者您是否只是玩弄代码以查看哪些有效/根据您的经验得出了答案?我很想了解更多关于 C++ 模板的信息,特别是 C++11
猜你喜欢
  • 2019-11-22
  • 2023-04-01
  • 1970-01-01
  • 2011-05-28
  • 2018-01-29
  • 1970-01-01
  • 2021-12-21
  • 2021-10-18
  • 2011-08-28
相关资源
最近更新 更多