Re: Vecotor of Pairs
arnuld wrote:
I know the line which causes the error but unable to find out the why. The
line in STEP 4, "std::ostream_iterator<stint>( std::cout, "\n" ), is the
source of error:
/* C++ Primer - 4/e
*
* CHAPTER 10 - Associative Containers
*
* EXERCISE - 10.1
* Write a program to read a sequence of strings and ints, storing
* each into a pair. Store the pairs into a Vector.
*
*/
/* We will solve this problem in 4 steps
1.) Define all the variables we need.
2.) Get input and store that into the pair.
3.) store the respective pair into the Vector.
4.) print the vector ( to see if the program really worked or not).
*/
#include <iostream>
#include <string>
#include <vector>
#include <utility>
#include <algorithm>
#include <iterator>
int main()
{
/* STEP 1
each pair will represent a string as first member connected to an int
as second memeber.
*/
typedef std::pair<std::string, int> stint;
std::vector<stint> vec_stint;
/* STEP 2 & 3 */
std::string ele1;
int ele2;
std::cout << "Please enter a word at 1st input and
a number at 2nd iput and so on"
<< std::endl;
while( std::cin >> ele1 >> ele2 )
{
stint current_stint = make_pair( ele1, ele2 );
vec_stint.push_back(current_stint );
}
/* STEP 4 */
std::copy( vec_stint.begin(), vec_stint.end(),
std::ostream_iterator<stint>( std::cout, "\n" ));
return 0;
}
The problem is that std::pair<> does not define operator<<. This is one of
the major shortcomings of standard containers: they don't have IO and you
cannot work around it since you are not allowed to add the necessary
overloads to namespace standard. Instead of providing a reasonable default,
the standard chose to not provide IO at all. I don't think the decision was
wise, but we have to live with it. It's very unlikely to change.
This is one of the very few instances where inheriting from standard
containers provides a viable solution. If you do:
struct stint : public std::pair< std:.string, int > {
// some constructors
friend
std::ostream & operator<< ( std::ostream & str, stint const & value ) {
...
}
};
your code should compile (however, you would need to replace make_pair with
the correct constructor calls. You could also consider private inheritance
+ using directives (one can argue that that would be better).
Now, for a class like std::pair, this sort of public inheritance saves you
almost no writing; but for classes like std::vector it can be a usefull
technique to create type-clones (as opposed to type-aliases obtained by
typedef).
Alternatively, you could define your own streams outside namespace standard.
Finally, you can write the IO without using operator<< on pairs.
Best
Kai-Uwe Bux