我想创建一个模板类,该模板类具有STL容器的迭代器作为成员。那就是我走了多远:
#include <iostream>
#include <vector>
using namespace std;
template<typename Element, template <class> class StdLibContainer>
struct ClassHoldingAnIteratorToAStandardContainer
{
ClassHoldingAnIteratorToAStandardContainer(){}
typename StdLibContainer<Element*>::iterator std_lib_iterator;
};
int main()
{
vector<int> vec{1,2,3};
ClassHoldingAnIteratorToAStandardContainer<int,vector<int>> holding_iterator_to_vec;
//DOES NOT WORK, compiler says: expected a class template, got ‘std::vector<int>’
return 0;
}
您能解释一下语法template <typename> class StdLibContainer
吗?
我在stackoverflow上的某个地方找到了它。但是我不明白。
如何创建ClassHoldingAnIteratorToAStandardContainer
的实例?到目前为止,我所有的尝试都失败了。编译器总是给出错误消息:`期望一个类模板,得到了'std :: vector'
在上面的示例中,我想分配holding_iterator_to_vec
vec.begin()
。
答案 0 :(得分:1)
template <typename> class
与template <class> class
相同。最初,引入模板时,它们允许两种等效形式:
template<class T> struct Foo {};
// or
template<typename T> struct Foo {};
不要问我为什么!但是,对于模板模板参数,情况并非如此:
template <template <class> typename T> struct Foo {};
是唯一允许的语法。显然,人们对此感到不满意,因此语法放松了。
关于第二个问题,std::vector
至少使用两个模板参数,数据类型和分配器。这就是为什么单个参数模板不会在C ++ 17之前删除它的原因。在C ++ 17之后,它将起作用。
要使其通用,请使用
template<template <class...> class Container> struct Foo{};
答案 1 :(得分:0)
除非您真的需要了解容器的类型,否则我强烈建议使ClassHoldingAnIteratorToAStandardContainer
与具体的容器类型无关。如果您只需要迭代器,这将更加简单和充分:
template<typename iterator>
struct iterator_wrapper {
iterator iter;
};
那是您需要拥有迭代器作为成员的最低要求:)。
我真的不知道您要使用迭代器做什么,所以仅出于示例的目的,让我们添加实际使用迭代器的方法。...
#include <iterator>
#include <vector>
#include <iostream>
template<typename iterator>
struct iterator_wrapper {
using value_type = typename std::iterator_traits<iterator>::value_type;
iterator iter;
bool operator!=(const iterator& other) { return iter != other;}
iterator_wrapper& operator++(){
++iter;
return *this;
}
const value_type& operator*() { return *iter; }
};
template <typename iterator>
iterator_wrapper<iterator> wrap_iterator(iterator it) {
return {it};
}
int main() {
std::vector<int> vec{1,2,3};
auto it = wrap_iterator(vec.begin());
for (;it != vec.end();++it) std::cout << *it;
}
您的代码中也有问题。
typename StdLibContainer<Element*>::iterator
用于指针容器,而在主容器中则有int
个。如果要从容器类型推断出迭代器类型,则可以这样进行操作:
template <typename container,
typename iterator = typename container::iterator>
iterator_wrapper<iterator> wrap_begin(container& c) {
return {c.begin()};
}
这使得创建iterator_wrapper
变得如此简单
auto x = wrap_begin(vec);
请注意,此答案适用于C ++ 11,在较新的标准中,有推论指南使此类make_x
方法或多或少成为多余的afaik。