如何将具有不同容器的模板类(适配器)声明为模板参数? 比如我需要声明类:
template<typename T, typename Container>
class MyMultibyteString
{
Container buffer;
...
};
我希望它基于 vector 。如何使其硬定义? (防止有人写这样的声明MyMultibyteString<int, vector<char>>
)。
另外,如何实现这样的构造:
MyMultibyteString<int, std::vector> mbs;
没有将模板参数传递给容器。
最佳答案
你应该使用模板模板参数:
template<typename T, template <typename, typename> class Container>
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
class MyMultibyteString
{
Container<T, std::allocator<T>> buffer;
// ...
};
这将允许您编写:
MyMultibyteString<int, std::vector> mbs;
这里是编译live example .编写上述内容的另一种方式可能是:
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
// ...
};
这里是对应的live example .
你唯一需要注意的是模板模板形参声明中的参数数量和类型必须与你要作为模板传递的相应类模板的定义中的参数数量和类型完全匹配参数,而不管其中一些参数可能具有默认值。
例如,the class template std::vector
accepts two template parameters (元素类型和分配器类型),虽然第二个有默认值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)
这意味着您将无法编写一个可以同时接受 std::set
的类模板。和 std::vector
作为模板模板参数,因为不像 std::vector
, the std::set
class template accepts three template parameters .
关于c++ - 带有模板容器的模板类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16596422/