 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Palik Imre Guest
|
Posted: Tue Sep 13, 2005 4:18 am Post subject: iterator_traits vs. back_insert_iterator |
|
|
Hi y'all,
According to my copy of the standard, the definition of the
back_inserter_iterator starts as
template <class Container>
class back_insert_iterator : public iterator<output_iterator_tag,void,void,void,void> {
accidentaly this means
iterator_traits<back_insert_iterator::value_type
is always void. I guess, this makes it pretty unsuitable for algorithms
that are somehow depending on the output type.
Is this a bug in the standard, or there are some deep thoughts behind it?
Thx.
ImRe
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
|
|
| Back to top |
|
 |
David Abrahams Guest
|
Posted: Wed Sep 14, 2005 5:33 am Post subject: Re: iterator_traits vs. back_insert_iterator |
|
|
[email]imre.palik.ext (AT) automation (DOT) siemens.com[/email] (Palik Imre) writes:
| Quote: | Hi y'all,
According to my copy of the standard, the definition of the
back_inserter_iterator starts as
template <class Container
class back_insert_iterator : public iterator
accidentaly this means
iterator_traits<back_insert_iterator::value_type
is always void.
|
It's not an accident.
| Quote: | I guess, this makes it pretty unsuitable for algorithms
that are somehow depending on the output type.
Is this a bug in the standard, or there are some deep thoughts behind it?
|
Well, the whole area of iterators' associated types is underspecified
in the standard, but this is not a bug. Output iterators have a _set_
of value types, so choosing a particular value_type may not make
sense. According to 24.3.1,
In the case of an output iterator, the types
iterator_traits<Iterator>::difference_type
iterator_traits<Iterator>::value_type are both defined as void.
--
Dave Abrahams
Boost Consulting
www.boost-consulting.com
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
|
|
| Back to top |
|
 |
Bo Persson Guest
|
Posted: Wed Sep 14, 2005 5:35 am Post subject: Re: iterator_traits vs. back_insert_iterator |
|
|
"Palik Imre" <imre.palik.ext (AT) automation (DOT) siemens.com> skrev i
meddelandet news:amfysabqth.fsf (AT) automation (DOT) siemens.com...
| Quote: | Hi y'all,
According to my copy of the standard, the definition of the
back_inserter_iterator starts as
template <class Container
class back_insert_iterator : public
iterator
accidentaly this means
iterator_traits<back_insert_iterator::value_type
is always void. I guess, this makes it pretty unsuitable for
algorithms
that are somehow depending on the output type.
Is this a bug in the standard, or there are some deep thoughts
behind it?
|
You cannot access the element after it is output (like printed!), so
its exact type is not interesting.
The only requirement is that
*iter = element;
will work.
Bo Persson
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
|
|
| Back to top |
|
 |
kuyper@wizard.net Guest
|
Posted: Wed Sep 14, 2005 5:40 am Post subject: Re: iterator_traits vs. back_insert_iterator |
|
|
Palik Imre wrote:
| Quote: | Hi y'all,
According to my copy of the standard, the definition of the
back_inserter_iterator starts as
template <class Container
class back_insert_iterator : public iterator
accidentaly this means
iterator_traits<back_insert_iterator::value_type
is always void. I guess, this makes it pretty unsuitable for algorithms
that are somehow depending on the output type.
Is this a bug in the standard, or there are some deep thoughts behind it?
|
std::back_insert_iterator<Container> is for inserting things into the
container. It's an output iterator. It isn't supposed to be used in
contexts where you need to retrieve a value, rather than write one. The
standard explicitly states that
std::iterator_traits<Iterator>::value_type is supposed to be void for
output iterators (24.3.1p1).
For an output iterator 'a', the only thing you're guaranteed to be
allowed to do with *a is to assign a T object into the result:
*a = t;
This could be achieved by giving *a a type of T&, and that's often true
for output iterators that are also input iterators. However, for a pure
output iterator it's possible for *a to return a class type for which
operator=(const T&) is defined.
That's exactly what back_insert_iterator<Container> does: operator*()
returns back_insert_operator&, and operator=(typename
Container::const_reference) performs the actual insertion.
If you're using an algorithm with an output iterator, that algorithm
has to be writing something to that output iterator (usually from an
input iterator). If the algorithm needs a value type to use for
intermediate steps, it can use
typename std::iterator_traits<InputIterator>::value_type
If that won't work with the output iterator, then the algorithm doesn't
make sense for that pair of iterator types.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
|
|
| Back to top |
|
 |
Palik Imre Guest
|
Posted: Wed Sep 14, 2005 2:26 pm Post subject: Re: iterator_traits vs. back_insert_iterator |
|
|
[email]bop (AT) gmb (DOT) dk[/email] ("Bo Persson") writes:
| Quote: | "Palik Imre" <imre.palik.ext (AT) automation (DOT) siemens.com> skrev i
meddelandet news:amfysabqth.fsf (AT) automation (DOT) siemens.com...
You cannot access the element after it is output (like printed!), so
its exact type is not interesting.
The only requirement is that
*iter = element;
will work.
|
In my case, allowing this assignability in the given algorithm, would
interfere with other parts of the program. Actually I had something like
this in mind:
template<typename InputIterator, typename OutputIterator, typename BinaryOperation>
OutputIterator
partialSum(InputIterator first, InputIterator last,
OutputIterator result, BinaryOperation binaryOp)
{
typedef typename std::iterator_traits<OutputIterator>::value_type ValueType;
if (first == last) return result;
ValueType value = ValueType();
while (first != last)
{
value = binaryOp(value, *first);
*result++ = value;
first++;
}
return ++result;
}
Thanks,
ImRe
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
|
|
| Back to top |
|
 |
Bo Persson Guest
|
Posted: Wed Sep 14, 2005 11:22 pm Post subject: Re: iterator_traits vs. back_insert_iterator |
|
|
"Palik Imre" <imre.palik.ext (AT) automation (DOT) siemens.com> skrev i
meddelandet news:ampsrc9mzb.fsf (AT) automation (DOT) siemens.com...
| Quote: | bop (AT) gmb (DOT) dk ("Bo Persson") writes:
"Palik Imre" <imre.palik.ext (AT) automation (DOT) siemens.com> skrev i
meddelandet news:amfysabqth.fsf (AT) automation (DOT) siemens.com...
You cannot access the element after it is output (like printed!),
so
its exact type is not interesting.
The only requirement is that
*iter = element;
will work.
In my case, allowing this assignability in the given algorithm,
would
interfere with other parts of the program. Actually I had
something like
this in mind:
template<typename InputIterator, typename OutputIterator, typename
BinaryOperation
OutputIterator
partialSum(InputIterator first, InputIterator last,
OutputIterator result, BinaryOperation binaryOp)
{
typedef typename std::iterator_traits
ValueType;
if (first == last) return result;
ValueType value = ValueType();
while (first != last)
{
value = binaryOp(value, *first);
*result++ = value;
first++;
}
return ++result;
}
|
Ok, then why don't you use the InputIterator::value_type instead? That
is the type of the values you are summing up.
The problem with an output iterator is that it may actually output the
value, like to the screen or a printer. Once it's printed, you cannot
add anything to it. :-)
You do know that there is a std::partial_sum already available in the
standard library, don't you?
Bo Persson
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
|
|
| Back to top |
|
 |
kuyper@wizard.net Guest
|
Posted: Thu Sep 15, 2005 5:30 am Post subject: Re: iterator_traits vs. back_insert_iterator |
|
|
Palik Imre wrote:
| Quote: | bop (AT) gmb (DOT) dk ("Bo Persson") writes:
"Palik Imre" <imre.palik.ext (AT) automation (DOT) siemens.com> skrev i
meddelandet news:amfysabqth.fsf (AT) automation (DOT) siemens.com...
You cannot access the element after it is output (like printed!), so
its exact type is not interesting.
The only requirement is that
*iter = element;
will work.
In my case, allowing this assignability in the given algorithm, would
interfere with other parts of the program. Actually I had something like
this in mind:
template<typename InputIterator, typename OutputIterator, typename BinaryOperation
OutputIterator
partialSum(InputIterator first, InputIterator last,
OutputIterator result, BinaryOperation binaryOp)
{
typedef typename std::iterator_traits
|
If you're willing to impose the requirement that BinaryOperation must
typedef a result_type, as would happen automatically if it derives from
std::binary_function<>, then the following would be the ideal solution:
typedef typename BinaryOperation::result_type ValueType;
Otherwise, the definition
typedef typename std::iterator_traits<InputIterator>::value_type
ValueType;
is likely to do the job in most cases.
That's not quite guaranteed. If the InputIterator's value type is A,
and the BinaryOperation's result type is B, and the OutputIterator's
value type is C, and if a value of type B can be converted to type C,
but not type A, then the following binary operator is going to cause
problems:
struct messed_up
{
B operator() (const A&, const A&) const;
B operator() (const B&, const B&) const;
};
Your function is very similar to std::partial_sum<>. By my reading of
section 26.4.3 of the C++ standard,
std::partial_sum<A_iterator, C_iterator, messed_up>()
is supposed to actually work, but I don't see how it could be written
to deal with this case.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|