26

I'm trying to learn C++ and right now I'm writing a program that needs to output a list of pairs of integers.

What is the best way to handle this? I don't have the boost library available on our linux computers at school, so I don't believe I can use boost::tuple.

Any suggestions?

Soo Wei Tan
  • 3,262
  • 2
  • 34
  • 36
Mithrax
  • 7,603
  • 18
  • 55
  • 60
  • 1
    If you have a sufficiently recent version of g++ that has tr1 support, `boost::tuple` is included as `std::tr1::tuple`; as others note in answers below, though, you can just use `std::pair` for pairs. – James McNellis Jan 29 '10 at 20:35

3 Answers3

31

Have a look at std::pair<object, object>

EDIT:

It's standard C++ and part of what is known as the STL (Standard Template Library). It's a collection of nice data structures that are generic (i.e. may be used to store any C++ object type). This particular structure is used to store a "tuple" or a pair of numbers together. It's basically an object with members "first" and "second" that refer to the first and second objects (of any type!) that you store in them.

So just declare an array of pair<int, int>, or better yet, use another STL type called the "vector" to make a dynamically-sized list of pair<int, int>: vector<pair<int, int> > myList.

Hey what do you know! A dynamically-sized list of pairs already exists and it's called a map! Using it is as simple as #include <map> and declaring a map<int, int> myMap!!!

EDIT:

Yes, as pointed out, a map well "maps" one object to another, so you cannot have repeated lefthand-side values. If that's fine then a map is what you're looking for, otherwise stick to the vector of pair.... or take a look at multimaps.

std::map, std::multimap

Mahmoud Al-Qudsi
  • 28,357
  • 12
  • 85
  • 125
  • Note that outputting the pair will not be handled by `cout` (as it is for `int` or `double`) -- you will have to handle it separately. – dirkgently Jan 29 '10 at 20:34
  • 5
    In C++98 and C++03, you must use `vector >` (notice the space at the end!) because `>>` parses as "right shift". This will be fixed in C++0x. – ephemient Jan 29 '10 at 20:48
  • @ephemient Interesting... I bet that generates a very helpful compiler error. ;) – Nick Bolton Jan 29 '10 at 21:41
  • 6
    -1 because map isn't the same as treating pairs of values. Map does what it name says: maps one Key-value to another value. So, if using map, you can't have repetitions of the left-value. – Bruno Brant Jan 29 '10 at 21:41
  • 1
    @Bruno Yes you can - std::multimap –  Jan 30 '10 at 09:54
  • 2
    Neither `std::map` nor `std::multimap` are "a list of pairs". Lists retain their order, map collections do not. – Ben Voigt Nov 21 '14 at 15:13
19

Use std::pair?

#include <utility>
#include <iostream>

int main() {
    std::pair <int, int> p = std::make_pair( 1, 2 );
    std::cout << p.first << " " << p.second << std::endl;
}

You can make a vector of pairs:

typedef std::pair <int, int> IntPair;

...

std::vector <IntPair> pairs;
pairs.push_back( std::make_pair( 1, 2 ) );
pairs.push_back( std::make_pair( 3, 4 ) );
  • Would you suggest std::pair over map? – Mithrax Jan 29 '10 at 20:42
  • Mithrax, map is just a wrapper around pair. It uses the pair code internally. – Mahmoud Al-Qudsi Jan 29 '10 at 20:45
  • 1
    @Mithrax That depends what you want to do with the pairs. If one is a key and one is a value, then you should use std::map, which is in fact implemented using std::pair. –  Jan 29 '10 at 20:45
  • 3
    @Computer Guru map is not "just a wrapper" around pair. If anything it is a wrapper around a red-black balanced binary tree. –  Jan 29 '10 at 20:46
  • Sure. Versus a vector which would be an array list wrapper of pair. Point is, at the end of the day, you can't suggest pair instead of map because they're apples and oranges. One of them is a basic datastructure that represents a tuple, the other USES the tuple to make an even larger structure :) Keep in mind the OP is a beginner to C++ – Mahmoud Al-Qudsi Jan 29 '10 at 20:49
  • Nice answer, I just want to add that in `C++11`, creating vector of pairs is really easy: `std::vector> pairs = {{1,2}, {3,4}, {5,6}};` – Akavall Aug 14 '14 at 19:49
9

While std::pair is the best approach to use, I'm surprised nobody mentioned pre-stl solution:

struct Pair {
    int first;
    int second;
};

It is worrying that people think that they need boost for such a trivial problem.

shura
  • 694
  • 5
  • 9
  • 2
    Pre-STL like in pre-standard, previous millennium? And you wonder why nobody mentioned it? Additionally, your code lacks several important/nice features of `std::pair` so it doesn’t even serve for illustration purpose. In fact, what’s the purpose of mentioning this method at all? – Konrad Rudolph Jan 31 '10 at 13:59
  • 1
    Konrad, I did say that std::pair is better. I don't see why my code doesn't serve for illustration purpose. My main point was that sometimes people forget about simple solutions. – shura Jan 31 '10 at 14:09
  • 2
    If you're just trying to learn C++, this is easily the best answer presented. It's simple, uncomplicated and easy to adapt to other problems. Once they get used to struct, adapting to class and providing methods for things like MyObject.SecondValue is easy to teach. Combined with the array suggestion above (ie Pair[] MyValues) there's really no reason not to accept this answer. – nathanchere Feb 04 '10 at 23:50
  • I absolutely agree with nathanchere, for teaching purposes this is easily the best answer. Regardless of whether production code would define a new type when std::pair already exists, someone first learning C++ should be introduced to how it is done. – Darryl Nov 21 '14 at 14:47
  • 1
    Pardon my potential ignorance; *where* is it stated that `pair` has anything to do with the Boost? I'm referring to this: `It is worrying that people think that they need boost for such a trivial problem.` STL != Boost? – Super Cat Sep 03 '15 at 21:53