c++c++11stdvectorstd-pairlist-initialization

List-initialization of vector of pairs


Note: Please don't close the question just because the root cause was due to comma operator. The value of the question was to let the community understand the failure of:

std::vector<std::pair<int, int>> vpairs_third{(0, 1), (0, -1)};

was due to comma operator.

I am list-initializing a vector holding pairs of ints.

I understand the following works as expected:

std::vector<std::pair<int, int>> vpairs_first{std::make_pair(0, 1), std::make_pair(0, -1)};
std::vector<std::pair<int, int>> vpairs_second{{0, 1}, {0, -1}};

However, would someone explain why the following doesn't work?

std::vector<std::pair<int, int>> vpairs_third{(0, 1), (0, -1)};

Solution

  • When it comes to your question about list initialization of a vector of pairs, it's really cool that you've noticed the different behaviors here.

    Your first two examples are spot-on. In the first case, you're explicitly creating pairs using std::make_pair, which is the standard way to create a pair object before C++11, and it still works perfectly fine:

    std::vector<std::pair<int, int>> vpairs_first{std::make_pair(0, 1), std::make_pair(0, -1)};
    

    In the second case, you're utilizing uniform initialization introduced in C++11, which is also totally valid and a bit more concise:

    std::vector<std::pair<int, int>> vpairs_second{{0, 1}, {0, -1}};
    

    Now, for the tricky part! The third example is a bit of a gotcha. You're using parentheses () instead of braces {}, and inside the parentheses, you have expressions separated by commas:

    std::vector<std::pair<int, int>> vpairs_third{(0, 1), (0, -1)};
    

    In C++, when you separate expressions with a comma like that, it's actually using the comma operator, which evaluates both of its operands and returns the result of the second operand. So (0, 1) evaluates to 1 and (0, -1) evaluates to -1. What you're actually trying to do here is something like this:

    std::vector<int> some_vector{1, -1};
    

    But that's not what you want since vpairs_third is supposed to be a vector of pairs, not ints. So the compiler gets confused and gives you an error because you're trying to initialize a vector of pairs with just ints.

    Stick to using braces {} for list initialization to avoid that comma operator confusion and you'll be golden. Keep experimenting with C++, it's a great way to learn the ins and outs of the language!