value_type of back_inserter?

D

Daniel T.

The line marked (1) below compiles fine and does exactly what I would
expect, but the line marked (2) does not compile at all on my system.

error: variable or field 'bar' declared void

My question is, does the standard dictate that the value_type of a
back_inserter is 'void'? If so, why? I would expect the value_type of a
back_inserter to be the same as the value_type of the container it wraps.


template < typename It >
void foo( It it ) {
typename iterator_traits<It>::value_type bar;
cin >> bar;
*it++ = bar;
}

int main() {
vector<int> vec( 1 );
foo( vec.begin() ); // (1)
cout << vec.front();

vector<double> vec2;
foo( back_inserter( vec2 ) ); // (2)
cout << vec2.front();
}
 
A

Asongala

The source code in stl_iterator.h:

template<typename _Container>
class back_insert_iterator
: public iterator<output_iterator_tag, void, void, void, void>
{
....

The output iterator means write only.
 
D

Daniel T.

The source code in stl_iterator.h:

template<typename _Container>
class back_insert_iterator
: public iterator<output_iterator_tag, void, void, void, void>
{
...

The output iterator means write only.

Is this then dictated by the standard? Why would the value_type of an
output iterator be void?
 
T

Thomas Tutone

Daniel said:
Is this then dictated by the standard?

Yes, in the sense that it is permissible under the standard that an
output iterator be write-only.
Why would the value_type of an
output iterator be void?

Because that's the essence of an output iterator - you can send a value
to it, but you can't necessarily read a value from it.

Take a look at the SGI STL reference on output iterators:

http://www.sgi.com/tech/stl/Iterators.html
http://www.sgi.com/tech/stl/OutputIterator.html

Best regards,

Tom
 
D

Daniel T.

"Thomas Tutone said:
Yes, in the sense that it is permissible under the standard that an
output iterator be write-only.


Because that's the essence of an output iterator - you can send a value
to it, but you can't necessarily read a value from it.

Take a look at the SGI STL reference on output iterators:

http://www.sgi.com/tech/stl/Iterators.html
http://www.sgi.com/tech/stl/OutputIterator.html

Thank you, the specific comments about Output Iterators above was
helpful. Especially the comment: "...for an Output Iterator, in the
expression *x = t, there is no reason why operator= must take a unique
type."
 
M

Maxim Yegorushkin

Daniel said:
The line marked (1) below compiles fine and does exactly what I would
expect, but the line marked (2) does not compile at all on my system.

error: variable or field 'bar' declared void

My question is, does the standard dictate that the value_type of a
back_inserter is 'void'? If so, why? I would expect the value_type of a
back_inserter to be the same as the value_type of the container it wraps.


template < typename It >
void foo( It it ) {
typename iterator_traits<It>::value_type bar;
cin >> bar;
*it++ = bar;
}

int main() {
vector<int> vec( 1 );
foo( vec.begin() ); // (1)
cout << vec.front();

vector<double> vec2;
foo( back_inserter( vec2 ) ); // (2)
cout << vec2.front();
}

As a workaround for already mentioned issues you could use the
following trick:

#include <iostream>
#include <vector>
#include <iterator>

using namespace std;

struct S
{
S const& self_const() { return *this; }

// false convesion, never used
template<class C>
operator back_insert_iterator<C>&();

template<class T>
operator T() const
{
T t;
cin >> t;
return t;
}
};

template < typename It >
void foo( It it )
{
*it = S().self_const();
}

int main() {
vector<int> vec( 1 );
foo( vec.begin() ); // (1)
cout << vec.front();

vector<double> vec2;
foo( back_inserter( vec2 ) ); // (2)
cout << vec2.front();

}

I'm not sure if the standard guarantees it must work. g++ 4.1 compiles
it fine, comeau online does not. You may also need to add more false
conversion functions to circumvent overload resolution should you
decide to use the trick.

P.S. Just wasted 30 minutes for fun thinking about the problem. Would
not use in production code as tricky code as this piece. Keep it
simple...
 
P

Pete Becker

Daniel said:
Is this then dictated by the standard? Why would the value_type of an
output iterator be void?

What else can it be? You can assign to *iter, but you can't look at it.
So the value_type isn't actually meaningful, and void seems to be the
best analog of no-meaningful-type. Output iterators do have the notion
of types that are "writable to the ... iterator", but that's much
broader than a value type, and there's no general notation in C++ for
representing a set of types.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top