创建容器的模板类

Creating a template class of a container

本文关键字:创建      更新时间:2023-10-16

我试图创建一个类作为容器包装器,像这样

#include <vector>
template <typename T, typename U>
class Test {
T<U> list;
};
int main() {
Test<std::vector, int> test;
}

但这行不通。我知道当我这样使用它时它会起作用

#include <vector>
template <typename T>
class Test {
T list;
};
int main() {
Test<std::vector<int>> test;
}

但是我将如何写我的插入?

template <typename T>
class Test {
T list;
public:
void insert(??? element) {
...
}
};

TIA, 奈良濑

最简单的是

template <typename T>
class Test {
....
void insert(const typename T::value_type& element);

和/或,为了完整性和移动语义合规性:

void insert(typename T::value_type&& element);
但这

行不通。

对于您的第一个Test片段,由于std::vector有两个模板参数,value_typeallocator_type,我们必须在使用模板模板参数T声明中指定这些模板参数的存在,如下所示。 在这里我使用可变参数,然后T<U...>变得合法 删除了T = std::vector和编译错误。

我将如何写我的插页?

下面的代码还显示了Test::insert的实现示例。 由于此方法可以接受 C++11 及以上版本中的左值和右值引用,因此在这里我将转发引用(即 Scott Meyers 所说的通用引用)应用于它。 在这种方法中,我们不需要在Test::insert定义中指定Test::list的值类型,将错误的类型传递给Test::insert会导致编译错误。 如果需要值类型std::vector,可以使用成员类型std::vector::value_type

template <template<class...> class T, class ...U>
class Test
{
T<U...> list;
public:
template<class ...V>
void insert(V&& ...element) {
list.insert(std::forward<V>(element)...);
}
typename T<U...>::iterator begin() noexcept {
return list.begin();
}
typename T<U...>::iterator end() noexcept {
return list.end();
}
using value_type = typename T<U...>::value_type;
};

这是一个使用示例,std::vector

演示 (标准::矢量)

static_assert(
std::is_same<Test<std::vector, int>::value_type, int>::value, "oops!"); // OK.
Test<std::vector, int> test; // OK
test.insert(test.end(), 11);
test.insert(test.end(), 99);
for(auto it = test.begin(); it != test.end(); ++it){
std::cout << *it << std::endl;
}

作为另一个示例,此包装类还与std::map一起使用,如下所示:

演示 (标准::地图)

static_assert(
std::is_same<Test<std::map, int, int>::value_type, std::pair<const int, int>>::value, "oops!"); // OK.
Test<std::map, int, int> test; // OK
test.insert(std::make_pair(1, 11));
test.insert(std::make_pair(2, 99));
for(auto it = test.begin(); it!= test.end(); ++it){
std::cout << it->first << ", " << it->second << std::endl;
}

最后,这是第二个代码段的固定版本:

演示 (标准::矢量)

演示 (标准::设置)

template <class T>
class Test
{
T list;
public:
template<class ...V>
void insert(V&& ...element) {
list.insert(std::forward<V>(element)...);
}
typename T::iterator begin() noexcept {
return list.begin();
}
typename T::iterator end() noexcept {
return list.end();
}
using value_type = typename T::value_type;
};