Reputation: 370
I want to write templated function that
Here is the piece of code I have written but produces compilation error
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 produced are :
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());
Another snippet I wrote is
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 produced are :
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>)’
Please elaborate what errors mean and their cause of occurrence. Also suggest how to achieve the desired goal.
I will be grateful if you could suggest some sources for a novice to understand iterators.
Upvotes: 1
Views: 389
Reputation: 7109
Regarding your first question, you can simply use the iterator as the template type and use 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;
}
Using iterator_traits
also works and is a better solution since it will also work for pointers (that naturally do not have the value_type
member; thanks to Jarod42 for pointing this out):
template <typename Iterator>
void printContainer(Iterator itBegin,
Iterator itEnd)
{
copy(itBegin, itEnd, ostream_iterator<typename iterator_traits<Iterator>::value_type>(cout, " "));
cout << endl;
}
Starting with C++14, you can also use decltype
and decay_t
:
template <typename Iterator>
void printContainer(Iterator itBegin,
Iterator itEnd)
{
copy(itBegin, itEnd, ostream_iterator<decay_t<decltype(*itBegin)>>(cout, " "));
cout << endl;
}
Regarding your other tries, there's no ForwardIterator1
defined in your function and value_type
is a typedef
, not a function.
Upvotes: 5