36

What is the difference regarding memory allocation and efficiency between using a struct with two fields and a pair?

Soo Wei Tan
  • 3,262
  • 2
  • 34
  • 36
Tamara Wijsman
  • 12,198
  • 8
  • 53
  • 82

6 Answers6

28

std::pair provides pre-written constructors and comparison operators. This also allows them to be stored in containers like std::map without you needing to write, for example, the copy constructor or strict weak ordering via operator < (such as required by std::map). If you don't write them you can't make a mistake (remember how strict weak ordering works?) so it's more reliable just to use std::pair.

Björn Pollex
  • 75,346
  • 28
  • 201
  • 283
AshleysBrain
  • 22,335
  • 15
  • 88
  • 124
  • 1
    I don't think std::pair provides any constructors or operators for its members. What exactly are you thinking of? – Manuel Feb 10 '10 at 11:16
  • 1
    @Manuel, actually I just checked and sure enough, `pair` provides a default ctor, and a template copy ctor. Makes sense -- this way, in each case, `pair` allows calling it if & only if the underlying types allow it. – j_random_hacker Feb 10 '10 at 11:26
  • 1
    Yes but the OP seemed to be implying that std::pair *magically* generated those members for the underlying types. It's weird that this answer is the one that got accepted. – Manuel Feb 10 '10 at 11:33
  • 1
    The wording could have been a little better but I do think AshleysBrain knows what (s)he's talking about. – sellibitze Feb 10 '10 at 11:59
  • 1
    Edited to try and clarify the wording. – AshleysBrain Feb 10 '10 at 13:57
  • 2
    I think this warrants a mentioning of `std::make_pair()`, which is rather convenient in many circumstances, especially so in connection with the new meaning of `auto`. – sbi Dec 18 '12 at 08:08
  • Does the fact std::pair has a constructor make it a little bit slower than a struct without constructor? if we add millions of items to a std::map for example ? – Basj Jul 30 '17 at 11:31
23

std::pair comes with a number of constructors and operators.

A struct allow named fields (other than first and second) and is ready to be extended at any time.

Prefer a struct when you can. It may involve some overhead, but is definitely easier for maintenance.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
Matthieu M.
  • 287,565
  • 48
  • 449
  • 722
  • 26
    +1 for the maintenance comment. I worked with a group of engineers from NJ who tried to do everything (and I mean everything) with the STL, and rather than creating appropriate classes/structs when the design indicated, they used an STL container. Code was littered with "if (route.first.second[*iter].first) { ... }". Ugh! – Don Wakefield Feb 11 '10 at 14:50
7

In terms of memory allocation and efficiency, there is no difference -- since that's exactly what a std::pair is.

j_random_hacker
  • 50,331
  • 10
  • 105
  • 169
  • That is what answers what I was wondering about, I suddenly realized that efficiency really depends on what you would do so is a bit too much information. I'm going to accept AshleysBrain's question for thinking further... – Tamara Wijsman Feb 10 '10 at 11:10
  • 2
    No problem, but it would have made more sense to ask about comparing ease-of-use if that's what you're interested in. Naveen and I both answered the question as stated. (Not complaining, just saying...) – j_random_hacker Feb 10 '10 at 11:15
  • Hmm, seem to have made a serious typo in my comment. "That is the answer I was wondering about" it should have been. I gave AshleysBrain the accepted answer as he was was quick and gave a good answer, just like you. It was hard to choose, but I went for the one who would benefit most. – Tamara Wijsman Feb 13 '10 at 00:54
  • Is there a source file / header showing that a pair is coded internally as a struct ? – Basj Jul 30 '17 at 11:32
  • @Basj: I don't have the C++09 standard on hand, but I believe this is required by the standard. – j_random_hacker Jul 30 '17 at 16:04
  • @j_random_hacker: If you find the C++09 standard, let me know ;) – Lightness Races in Orbit May 01 '18 at 09:41
  • @LightnessRacesinOrbit: Whoops, obviously that should have been "C++11". – j_random_hacker May 01 '18 at 11:41
2

No difference in terms of memory allocation or efficiency. In fact, in the STL implementation I am using pair is defined as struct pair

Naveen
  • 74,600
  • 47
  • 176
  • 233
  • What STL implementation are you using ? – Benoît Feb 10 '10 at 11:09
  • I am using the one which comes with VC9 compiler. – Naveen Feb 10 '10 at 11:13
  • 1
    Yes, this adheres to the common convention that if a user-defined type exposes public data members (like `pair` does with `first` and `second`) then it has to be a `struct`. – Manuel Feb 10 '10 at 11:17
  • Could be a `class` with `first` and `second` declared in a `public` section. According to the interface, the `first` and `second` members must be public; doesn't state whether it must be a `class` or `struct`. – Thomas Matthews Feb 10 '10 at 17:40
  • 2
    @Thomas Matthews: There is no semantic difference whatsoever between `struct X { ... };` and `class X { public: ... };`. (Unlike in C# for example.) – j_random_hacker Feb 11 '10 at 04:08
  • This seems to be in contradiction with Basj's answer. – Keith M Feb 07 '19 at 19:01
2

As this isn't mentioned above, if you want the benefits of your own name, but the advantages of std::pair (or any other objects), you can use "using" ( from c++11 onwards). You can set this in your namespace or class declaration.

In fact this is how many of my classes now start out...

using myPair = pair<int,string>;

cf. C++ reference. for more documentation.

Konchog
  • 1,920
  • 19
  • 23
  • 1
    While true, this still has the `.first` and `.second` "problem". – infinitezero Dec 01 '21 at 09:53
  • @infinitezero - that's correct. It's when I start seeing first.second.first, or needing to add functions, that I know it's time to turn the alias into a struct. – Konchog Dec 01 '21 at 10:45
1

As stated in std::pair<int, int> vs struct with two int's a struct will probably be a little bit faster because no initialization is made.

Basj
  • 41,386
  • 99
  • 383
  • 673