16

I didn't find anyone answering this, is there any difference between the following :

v.push_back({x, y});

and :

v.push_back(make_pair(x, y));

Assuming that v was declared this way :

vector<pair<int,int> > v;
  • One way to find out is to look at the resulting assembly language –  Sep 08 '18 at 14:28
  • No, there isn't. The former is newer, post C++11 language feature. `std::make_pair` has been around for a long time. – Sam Varshavchik Sep 08 '18 at 14:28
  • The first creates (indirect) a temporary object which is passed to `push_back`. The other calls a function which creates the object which is returned and passed to the function. There might be more operations for the `make_pair` variant, but the end result (a pair containing `x` and `y` being pushed to the end of the vector) is still the same in both. – Some programmer dude Sep 08 '18 at 14:28
  • 10
    *Take in consideration that I'm asking for competitive programming usage* -- Explain exactly what this is supposed to mean, i.e. "competitive programming". You either write solid, maintainable code or you don't. – PaulMcKenzie Sep 08 '18 at 14:57
  • No there are no difference. – Oliv Sep 08 '18 at 15:03
  • @PaulMcKenzie it's supposed to mean that I don't only care about the result, I care also about the complexity and memory usage... every detail counts even if it's small... – Noueman Khalikine Sep 08 '18 at 15:17
  • @Someprogrammerdude Thank your Sir , that's what I was looking for ! – Noueman Khalikine Sep 08 '18 at 15:20
  • 1
    @NouemanKhalikine *I don't only care about the result, I care also about the complexity and memory usage* -- So solid programming doesn't care about complexity and memory usage?? What I see on this site when it comes to "competitive programming" is more often than not, the code looks like a mess and is disorganized, stupid `typedef` statements that obfuscate the code so that it is very hard to debug, just plain bad usage of C++, etc. You can write code that is maintainable, easy to debug, efficient, etc. all without writing code in a haphazard and bad way. – PaulMcKenzie Sep 08 '18 at 15:39
  • 3
    Sigh. There are still people who are stuck in the 80s. See if you can find a relevant piece of code where `>> 1` has the same effect, yet is more efficient than `*2` on any relevant C++ compiler today. I'll wait. – sehe Dec 26 '18 at 01:42
  • 2
    @sehe `>>1` rarely has the same effect as `*2` — the former divides by 2, the latter multiplies by 2 :) – fredoverflow Dec 26 '18 at 10:46
  • What was down vote for? I see no problem with this question. The 2nd form - older syntax triggers an extra copy-elision at compile-time on modern compilers. But the output binary is expected to be identical. – Red.Wave Mar 01 '19 at 15:48

3 Answers3

14

I think you might have accepted that answer a little too quickly. The commonly accepted way to do this is like this:

vec.emplace_back (x, y);

And if you look at Godbolt, you can see that this inlines everything (which may or may not be what you want):

https://godbolt.org/z/aCl02d

Run it at Wandbox:

https://wandbox.org/permlink/uo3OqlS2X4s5YpB6

Code:

#include <vector>
#include <iostream>

int x = 1;
int y = 2;
std::vector<std::pair<int,int>> vec;

int main () {
    vec.push_back(std::make_pair(x, y));
    std::cout << "make_pair done\n";
    vec.push_back({x, y});
    std::cout << "push_back done\n";
    vec.emplace_back (x, y);
    std::cout << "emplace_back done\n";

    for (std::pair <int, int> p : vec)
    {
        std::cout << p.first << ", " << p.second << "\n";
    }
}

Output:

make_pair done
push_back done
emplace_back done
1, 2
1, 2
1, 2

Of course, everything runs faster if you reserve the appropriate number of elements in the vector up front. Maybe that's what the people posing this question are really wanting you to say.

Paul Sanders
  • 24,133
  • 4
  • 26
  • 48
  • 3
    Yes, I know emplace_back faster than push_back, thanks a lot for pointing it out ;) It just was not part of my concern on this subject ! – Noueman Khalikine Sep 09 '18 at 01:34
8

I tried this in an online compiler, and as far as I can see the optimized assembly for make_pair is identical to {} syntax.

https://godbolt.org/z/P7Ugkt

Hitobat
  • 2,847
  • 1
  • 16
  • 12
5

{x, y} in v.push_back({x, y}) is aggregate initialization (since C++11) of v's value_type, whereas std::make_pair is a function creating an std::pair with types deduced from its arguments.

One advantage of push_back({x, y}) over emplace_back(x, y) is that you could keep small structures simple (without constructors) like this:

#include <vector>

struct A {
    int x;
    int y;
    // A(int _x, int _y) : x{_x}, y{_y} {}
};

int f()
{
    std::vector<A> v;
    v.push_back({1, 2});
    // v.emplace_back(1, 2); // doesn't compile unless constructor is uncommented
}

Example.

Dev Null
  • 4,731
  • 1
  • 30
  • 46