I tested my wonderfull iterator iterator_pair and it works fine. For example
[code]
std::map<int, std::string> m;
std::string s = "Hello new iterator \"std::iterator_pair\"!";
std::istringstream is( s );
int i = 0;
std::transform( std::istream_iterator<std::string>( is ),
std::istream_iterator<std::string>(),
std::inserter( m, m.begin() ),
[&i]( const std::string &s ) { return ( std::make_pair( i++, s ) ); } );
std::vector<int> v1( m.size() );
std::vector<std::string> v2( m.size() );
std::copy( m.begin(), m.end(),
usr::make_iterator_pair( v1.begin(), v2.begin() ) );
for ( int x : v1 ) std::cout << x << ' ';
std::cout << std::endl;
for ( const std::string &s : v2 ) std::cout << s << ' ';
std::cout << std::endl;
[/code]
However it seems that I found a very serious defect of the C++ Standard.
If to change the code above the following way
[code]
std::map<int, std::string> m;
std::string s = "Hello new iterator \"std::iterator_pair\"!";
std::istringstream is( s );
int i = 0;
std::transform( std::istream_iterator<std::string>( is ),
std::istream_iterator<std::string>(),
std::inserter( m, m.begin() ),
[&i]( const std::string &s ) { return ( std::make_pair( i++, s ) ); } );
std::vector<int> v1;
std::vector<std::string> v2;
v1.reserve( m.size() );
v2.reserve( m.size() );
std::copy( m.begin(), m.end(),
usr::make_iterator_pair( std::back_inserter( v1 ), std::back_inserter( v2 ) ) );
for ( int x : v1 ) std::cout << x << ' ';
std::cout << std::endl;
for ( const std::string &s : v2 ) std::cout << s << ' ';
std::cout << std::endl;
[/code]
It will not be compiled. The problem is that std::back_inserter is an output iterator and its value_type is defined as void. As the result I get std::pair<void, void>.
Let's consider the following two iterators
std::ostream_iterator<std::string> it1( std::cout, "\n" );
std::ostream_iterator<int> it2( std::cout, "\n" );
They are different though the both have the same template definitions. What is the difference?
You may write
it1 = "abc";
it2 = 123;
but you may not write
it1 = 123;
it2 = "abc";
What does this mean?
It means that these two iterators have different value types!
And as we see value type is an integral and important part of these iterators. So these iterators have defined value types.
However in the C++ Standard they are defined such a way that their value_type is defined as void.
It is a serious defect of the standard. The value_type for output iterators shall not be defined as void because each output iterator including above mentioned and also std::back_insert_iterator, std::front_insert_iterator, and std::insert_iterator have concrete value types as I showed in the example above with std::ostream_iterator.
So each output iterator either shall have its defined value_type or retranslate the value_type of an underlined iterator.
Let's consider another simple example.
template <OutputIterator>
void SomeFunction( OutputIterator iterator )
{
// some code
}
And let's assume that we are going to define a variable inside the function body that will have the type that may be processed by iterator. As the iterator has value_type void there is no possibility to determine the type of the variable.
template <OutputIterator>
void SomeFunction( OutputIterator iterator )
{
WhatType? our_variable;
}
I am sure that all output iterators must have a concrete value_type that will differ from void.
воскресенье, 29 сентября 2013 г., 0:59:11 UTC+4 пользователь Vlad from Moscow написал: