当广义STL容器不知道迭代器的值类型时,如何使用模板化迭代器?

时间:2016-08-23 06:36:41

标签: c++ templates stl iterator

我想写模板函数

  • 接受2个迭代器
  • 使用* copy(在算法标准标题中定义)打印存储在容器中的内容。

以下是我编写的代码但产生编译错误

template <template<typename, typename> class Container, 
            typename Value, 
            typename Allocator = std::allocator<Value> >
void printContainer(Container<Value, Allocator>::iterator itBegin,
                    Container<Value, Allocator>::iterator itEnd)
{
        copy(itBegin, itEnd, ostream_iterator<Value>(cout, " "));
        cout << endl;
}

产生的错误是:

  error 1: variable or field ‘printContainer’ declared void
  void printContainer(Container<Value, Allocator>::iterator itBegin,
                                                   ^
  error 2: expected ‘)’ before ‘itBegin’
  void printContainer(Container<Value, Allocator>::iterator itBegin,
                                                            ^
  error 3: expected ‘)’ before ‘itEnd’
       Container<Value, Allocator>::iterator itEnd)
                                             ^
 p00441.cpp: In function ‘int main()’:
 p00441.cpp:10:39: error: ‘printContainer’ was not declared in this scope
   printContainer(inp.begin(), inp.end());

我写的另一个片段是

template<typename InputIterator>
void printContainer(InputIterator itBegin, InputIterator itEnd){
        //Trial 1
        copy(itBegin, itEnd, ostream_iterator< iterator_traits<ForwardIterator1>::value_type>(cout, " "));

        //Trial 2
        copy(itBegin, itEnd, ostream_iterator<value_type(itBegin)*>(cout, " "));
        cout << endl;
}

产生的错误是:

error 1: ‘ForwardIterator1’ was not declared in this scope
   copy(itBegin, itEnd, ostream_iterator< iterator_traits<ForwardIterator1>::value_type>(cout, " "));
                                                          ^
error 2: template argument 1 is invalid
   copy(itBegin, itEnd, ostream_iterator< iterator_traits<ForwardIterator1>::value_type>(cout, " "));
                                                                          ^
error 3: template argument 1 is invalid
   copy(itBegin, itEnd, ostream_iterator< iterator_traits<ForwardIterator1>::value_type>(cout, " "));
                                                                                       ^
error 3: type/value mismatch at argument 1 in template parameter list for ‘template<class _Tp, class _CharT, class _Traits> class std::ostream_iterator’
   copy(itBegin, itEnd, ostream_iterator<value_type(itBegin)*>(cout, " "));
                                                             ^
error 4:   expected a type, got ‘(value_type(itBegin) * <expression error>)’

请详细说明错误的含义及其发生的原因。还建议如何实现预期目标。

如果您能为新手提供一些理解迭代器的资料,我将不胜感激。

1 个答案:

答案 0 :(得分:5)

关于第一个问题,您只需使用迭代器作为模板类型并使用iterator::value_type

#include <iostream>
#include <vector>
#include <list>
#include <algorithm>
#include <iterator>

using namespace std;

template <typename Iterator>
void printContainer(Iterator itBegin,
                    Iterator itEnd)
{
        copy(itBegin, itEnd, ostream_iterator<typename Iterator::value_type>(cout, " "));
        cout << endl;
}

int main() {
    vector<int> v{1, 2, 3, 4, 5, 6};
    list<int>   l{1, 2, 3, 4, 5, 6};
    printContainer(begin(v), end(v));
    printContainer(begin(l), end(l));

    return 0;
}

https://ideone.com/DhUQ1t

使用iterator_traits也有效,是一个更好的解决方案,因为它也适用于指针(当然没有value_type成员;感谢Jarod42指出这一点):

template <typename Iterator>
void printContainer(Iterator itBegin,
                    Iterator itEnd)
{
        copy(itBegin, itEnd, ostream_iterator<typename iterator_traits<Iterator>::value_type>(cout, " "));
        cout << endl;
}

https://ideone.com/8N0ook

从C ++ 14开始,您还可以使用decltypedecay_t

template <typename Iterator>
void printContainer(Iterator itBegin,
                    Iterator itEnd)
{
        copy(itBegin, itEnd, ostream_iterator<decay_t<decltype(*itBegin)>>(cout, " "));
        cout << endl;
}

https://ideone.com/7MBsiL

关于您的其他尝试,您的函数中没有定义ForwardIterator1value_typetypedef,而不是函数。