2016-08-23 46 views
1

我想要寫模板函數如何在迭代器的值類型不知道廣義STL容器時使用模板化迭代器?

  • 接受2次迭代
  • 打印使用*副本(在算法標準報頭中定義)儲存在容器中的內容。

這裏是一段代碼我已經寫,但產生編譯錯誤

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>)’ 

請詳細說明錯誤的含義及其發生原因。同時建議如何達到預期的目標。

我將不勝感激,如果你可以建議一些新手理解迭代器的來源。

+0

我不完全清楚爲什麼'Container'或'Allocator'甚至是模板類型參數的一部分。不僅僅是一個'Iterator'工作?你仍然可以通過'std :: iterator_traits'解密它的值類型。 – WhozCraig

+0

@WhozCraig容器被使用,以便我可以傳遞一個通用容器的引用並使用container.size()來顯示所有元素。但迭代器更方便。 –

回答

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


關於你的其他的嘗試,有沒有ForwardIterator1在你的函數定義value_typetypedef,不是函數。

+2

'iterator_traits'優於'Iterator :: value_type',因爲前者與常規指針一起工作。 – Jarod42

+1

'decay_t'除了'decltype'之外還可以使用等價的代碼。 – Jarod42

+0

@ Jarod42:謝謝你指出這些事情。我已經更新了第一個,但我不確定第二個:「decay」的用法是什麼? – rainer