
December 6th, 2006, 08:13 PM
| | | Using copy for output
Hi all,
Given a list of int, it's rather easy to output them line by line:
std::copy(mylist.begin(), mylist.end(),
std::ostream_iterator<int>(cout, "\n");
Now, there's two ways in which I would like to generalize this:
First, I would like to be able to print a list of pointers to int.
However, I'm guessing this is not possible with copy, right?
I would have to:
for(std::list<int>::const_iterator it = mylist.begin(); it !=
mylist.end() ; ++it) cout << **it << "\n";
Right? Not possible with copy?
Another thing I would like to do it to had a character in-between each
printed int. For example:
If I have a list with 1,2,3,4,5 and I want to print " + " I would get 1
+ 2 + 3 + 4 + 5.
A solution is:
std::string str(" + ");
for(std::list<int>::const_iterator it = mylist.begin(); it !=
mylist.end() ; ++it) {
cout << **it;
std::list<int>::const_iterator aux = it;
if(++aux != mylist.end())
cout << str;
}
Is there any better way? Comments on this? Anyway to do this more
straightforwardly?
Regards,
Paulo Matos | 
December 6th, 2006, 08:13 PM
| | | Re: Using copy for output
Paulo Matos wrote: Quote:
If I have a list with 1,2,3,4,5 and I want to print " + " I would get 1
+ 2 + 3 + 4 + 5.
| std::copy(mylist.begin(), mylist.end(),
std::ostream_iterator<int>(cout, " + ");
--
-- Pete
Roundhouse Consulting, Ltd. ( www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." ( www.petebecker.com/tr1book) | 
December 6th, 2006, 08:45 PM
| | | Re: Using copy for output
Pete Becker escreveu: Quote:
Paulo Matos wrote: Quote:
If I have a list with 1,2,3,4,5 and I want to print " + " I would get 1
+ 2 + 3 + 4 + 5.
| >
std::copy(mylist.begin(), mylist.end(),
std::ostream_iterator<int>(cout, " + ");
>
| That's what's I did iintially with '\n' however, it's not the same
thing. The result of that is:
1 + 2 + 3 + 4 + 5 +
And I don't want the extra plus in the end. What about if the list
contains pointers to ints? | 
December 6th, 2006, 09:15 PM
| | | Re: Using copy for output
On 6 Dec 2006 13:05:01 -0800, "Paulo Matos" wrote: Quote:
>Pete Becker escreveu: Quote:
>Paulo Matos wrote: Quote:
If I have a list with 1,2,3,4,5 and I want to print " + " I would get 1
+ 2 + 3 + 4 + 5.
| >>
>std::copy(mylist.begin(), mylist.end(),
>std::ostream_iterator<int>(cout, " + ");
| >
>That's what's I did iintially with '\n' however, it's not the same
>thing. The result of that is:
>1 + 2 + 3 + 4 + 5 +
>
>And I don't want the extra plus in the end.
| add:
cout << "\b\b\b"; // works for some ostreams Quote: |
>What about if the list contains pointers to ints?
| I'd use a for loop anyway. copy is 'semantically' wrong for output.
Best wishes,
Roland Pibinger | 
December 6th, 2006, 10:35 PM
| | | Re: Using copy for output
Paulo Matos wrote: Quote:
Hi all,
>
Given a list of int, it's rather easy to output them line by line:
std::copy(mylist.begin(), mylist.end(),
std::ostream_iterator<int>(cout, "\n");
>
Now, there's two ways in which I would like to generalize this:
First, I would like to be able to print a list of pointers to int.
However, I'm guessing this is not possible with copy, right?
I would have to:
for(std::list<int>::const_iterator it = mylist.begin(); it !=
mylist.end() ; ++it) cout << **it << "\n";
>
Right? Not possible with copy?
Another thing I would like to do it to had a character in-between each
printed int. For example:
If I have a list with 1,2,3,4,5 and I want to print " + " I would get 1
+ 2 + 3 + 4 + 5.
A solution is:
std::string str(" + ");
for(std::list<int>::const_iterator it = mylist.begin(); it !=
mylist.end() ; ++it) {
cout << **it;
std::list<int>::const_iterator aux = it;
if(++aux != mylist.end())
cout << str;
}
>
Is there any better way? Comments on this? Anyway to do this more
straightforwardly?
>
Regards,
>
Paulo Matos
| With an operator<< overload...
#include <iostream>
#include <ostream>
#include <list>
#include <algorithm>
#include <iterator>
template< typename T >
class NSequence
{
T t;
public:
NSequence(const T& r_t) : t(r_t) { }
T operator() () { return t++; }
};
template< typename T >
std::ostream&
operator<<(std::ostream& os, std::list< T >& r_l)
{
std::copy( r_l.begin(),
--r_l.end(),
std::ostream_iterator< int >(os, " + "));
return os << *(--r_l.end());
}
int main()
{
std::list< int nlist;
// insert integers from 1 to 6
std::generate_n( std::back_inserter(nlist),
6,
NSequence< int >(1) );
// print ints with " + "
std::cout << nlist << std::endl;
}
/*
1 + 2 + 3 + 4 + 5 + 6
*/
If you need the same with a std::list< int* >,
i'ld suggest wrapping it in a templated class with a std::list member. | 
December 7th, 2006, 12:55 PM
| | | Re: Using copy for output
Paulo Matos wrote: Quote:
Pete Becker escreveu:
> Quote:
>Paulo Matos wrote: Quote:
>>If I have a list with 1,2,3,4,5 and I want to print " + " I would get 1
>>+ 2 + 3 + 4 + 5.
| >std::copy(mylist.begin(), mylist.end(),
>std::ostream_iterator<int>(cout, " + ");
>>
| >
That's what's I did iintially with '\n' however, it's not the same
thing. The result of that is:
1 + 2 + 3 + 4 + 5 +
>
| Whoops, sorry. As long as you've got a bidirectional iterator, you can
do this:
mylist::iterator end = mylist.end();
if (mylist.begin() != end)
{
--end;
std::copy(mylist.begin(), end,
std::ostream_iterator<int>(cout, " + "));
std::copy(--mylist.end(), end,
std::ostream_iterator<int>(cout, ""));
}
Alternatively, you can write an algorithm that takes an output stream
rather than an iterator:
template <class InIt>
void show(InIt first, ostream& str, const char *sep)
{
if (first != last)
str << *first++;
while (first != last)
str << sep << *first++;
}
--
-- Pete
Roundhouse Consulting, Ltd. ( www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." ( www.petebecker.com/tr1book) | 
December 7th, 2006, 01:05 PM
| | | Re: Using copy for output
Salt_Peter wrote: Quote: |
return os << *(--r_l.end());
| A note of caution here: this works if operator-- is a member of the
iterator type returned by end(), but doesn't work if it's a free
function. The problem is that -- modifies its argument. The call to
end() creates a temporary object, and you can't pass that to a
non-member function that takes its argument by reference.
--
-- Pete
Roundhouse Consulting, Ltd. ( www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." ( www.petebecker.com/tr1book) | 
December 7th, 2006, 01:55 PM
| | | Re: Using copy for output
Pete Becker wrote: Quote:
Salt_Peter wrote: Quote: |
return os << *(--r_l.end());
| >
A note of caution here: this works if operator-- is a member of the
iterator type returned by end(), but doesn't work if it's a free
function. The problem is that -- modifies its argument. The call to
end() creates a temporary object, and you can't pass that to a
non-member function that takes its argument by reference.
>
| Its a std::list so thats a bidirectional iterator with --iter and
iter-- member-operators available.
If the iterator involved was only a forward iterator, that would indeed
fail.
The warning about the temporary is relevant and for the record, i don't
like the above statement at all even if the reference to std::list<>
had been made const.
Thanks for your input. | 
December 7th, 2006, 02:15 PM
| | | Re: Using copy for output
Salt_Peter wrote: Quote:
Pete Becker wrote: Quote:
>Salt_Peter wrote: Quote: |
>> return os << *(--r_l.end());
| >A note of caution here: this works if operator-- is a member of the
>iterator type returned by end(), but doesn't work if it's a free
>function. The problem is that -- modifies its argument. The call to
>end() creates a temporary object, and you can't pass that to a
>non-member function that takes its argument by reference.
>>
| >
Its a std::list so thats a bidirectional iterator with --iter and
iter-- member-operators available.
| It's a std::list, so it provides a bidirectional iterator. The
requirement for bidirectional iterators is that the expressions --iter
and iter-- are both valid and have specified semantics. They are not
required to be implemented with member functions. If pre-increment is a
free function, --r_l.end() is ill-formed.
--
-- Pete
Roundhouse Consulting, Ltd. ( www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." ( www.petebecker.com/tr1book) | 
December 7th, 2006, 03:35 PM
| | | Re: Using copy for output
Thanks a lot for all your input. :) Great, I just learned some more C++
today! |
Posting Rules
| You may not post new threads You may not post replies You may not post attachments You may not edit your posts HTML code is Off | | | | | | What is Bytes?
We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights.
Get the best answers to your questions from over network members.
|