模板类与模板容器

DuX*_*N0N 37 c++ containers templates stl

如何使用不同的容器声明模板类(适配器)作为模板参数?例如,我需要声明类:

template<typename T, typename Container>
class MyMultibyteString
{
    Container buffer;
    ...
};
Run Code Online (Sandbox Code Playgroud)

而我希望它基于矢量.如何使其明确定义?(以防止有人写这样的声明MyMultibyteString<int, vector<char>>).

而且,如何实施这样的建设:

MyMultibyteString<int, std::vector> mbs;
Run Code Online (Sandbox Code Playgroud)

没有将模板参数传递给容器.

And*_*owl 73

您应该使用模板模板参数:

template<typename T, template <typename, typename> class Container>
//                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
class MyMultibyteString
{
    Container<T, std::allocator<T>> buffer;
    // ...
};
Run Code Online (Sandbox Code Playgroud)

这将允许你写:

MyMultibyteString<int, std::vector> mbs;
Run Code Online (Sandbox Code Playgroud)

这是一个编译实例.编写上述内容的另一种方法可能是:

template<typename T,
    template <typename, typename = std::allocator<T>> class Container>
//  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
class MyMultibyteString
{
    Container<T> buffer; // <== No more need to specify the second argument here
    // ...
};
Run Code Online (Sandbox Code Playgroud)

这是相应的实例.

您唯一需要注意的是模板模板参数声明中的参数的数量和类型必须与您要作为模板参数传递的相应类模板的定义中的参数的数量和类型完全匹配,无论其中一些参数可能具有默认值.

例如,类模板std::vector接受两个模板参数(元素类型和分配器类型),尽管第二个模板参数具有默认值std::allocator<T>.因此,你不能写:

template<typename T, template <typename> class Container>
//                             ^^^^^^^^
//                             Notice: just one template parameter declared!
class MyMultibyteString
{
    Container<T> buffer;
    // ...
};

// ...

MyMultibyteString<int, std::vector> mbs; // ERROR!
//                     ^^^^^^^^^^^
//                     The std::vector class template accepts *two*
//                     template parameters (even though the second
//                     one has a default argument)
Run Code Online (Sandbox Code Playgroud)

这意味着你将不能写一个单独的类模板,既可以接受std::set,并std::vector作为模板的模板参数,因为不像std::vector,std::set类模板接受3个模板参数.

  • @ScottJones关于你的陈述:`这意味着你将无法编写一个可以同时接受std :: set和std :: vector`的单个类模板:可变参数模板能否解决问题?http://stackoverflow.com/a/20499809/2436175 (3认同)
  • 多么伟大而彻底的答案。 (2认同)
  • “这意味着您将无法编写可以接受`std :: set`和`std :: vector`的单个类模板,因为`std :: set`可以接受三个模板参数”-什么关于可变参数模板?`template &lt;class ... Args&gt;` (2认同)

Kap*_*pil 10

解决这个问题的另一种方法是使用可变参数模板,你可以使用上面评论中建议的任何容器,这里是实现:

template<template <typename... Args> class Container,typename... Types>
class Test
{
    public:
    Container<Types...> test;

};
int main()
{
  Test<std::vector,int> t;
  Test<std::set,std::string> p;
  return 0;
}
Run Code Online (Sandbox Code Playgroud)