0

I ran into this odd asymmetry when attempting to initialize a std::array object without specifying either template parameter. Can someone explain why v3 and a4 works, but a3 fails to compile?

#include <vector>
#include <array>

int main()
{
    auto v1 = std::vector<std::pair<int,int>>{ {1,2}, {3,4} };
    auto v2 = std::vector{ std::pair{1,2}, std::pair{3,4} };
    auto v3 = std::vector{ std::pair{1,2}, {3,4} };
    auto v4 = std::vector{ std::initializer_list{ std::pair{1,2}, {3,4} } };

    auto a1 = std::array<std::pair<int,int>, 2>{ {{1,2}, {3,4}} };
    auto a2 = std::array{ std::pair{1,2}, std::pair{3,4} };
    auto a3 = std::array{ std::pair{1,2}, {3,4} }; // <= fails to compile
    auto a4 = std::array{ std::initializer_list{ std::pair{1,2}, {3,4} } };

    return 0;
}
<source>: In function 'int main()':
<source>:13:49: error: class template argument deduction failed:
   13 |     auto a3 = std::array{ std::pair{1,2}, {3,4} }; // <= fails to compile
      |                                                 ^
<source>:13:49: error: no matching function for call to 'array(std::pair<int, int>, <brace-enclosed initializer list>)'

EDIT: I don't necessarily agree that this question is similar to the ones mentioned, since those questions refer to std::array with the type specified, not a std::array without template parameters. Note: This isn't a strong opinion.

MarkB
  • 672
  • 2
  • 9
  • Huh. I'm kinda surprised the C++ type deduction rules handle deducing the templated type of `std::vector{ std::pair{1,2}, {3,4} };` without requiring all of the items to be explicitly typed. Type deduction has come a long way. – ShadowRanger Nov 16 '22 at 23:11
  • this is gcc 12.2, btw – MarkB Nov 16 '22 at 23:11
  • Can you specify which standard you're compiling against? C++ rules have been updating a lot. – ShadowRanger Nov 16 '22 at 23:12
  • What `-std=c++??` are you using? And obligatory [The Nightmare of Initialization in C++](https://www.youtube.com/watch?v=7DTlWPgX6zs). – Eljay Nov 16 '22 at 23:12
  • lol. the response to a question is "watch this 1hr video..." – MarkB Nov 16 '22 at 23:58
  • @ShadowRanger, -std=c++17 or -std=c++20 produce the same result – MarkB Nov 16 '22 at 23:59
  • Only one hour video about C++ object initialization? It was basically sole bad feature broken in C++11 and every next standard made it worse. – Öö Tiib Nov 17 '22 at 00:22
  • @ShadowRanger That's because `vector{pair{1,2}, {3,4}}` sees a `initializer_list`, which is also why `array{pair{1,2}, {3,4}}` doesn't work, because it can't be initialized with `initializer_list`. – Ranoiaetep Nov 17 '22 at 04:20
  • Note, for `v4`, did you actually meant to do `vector(initializer_list{pair{1,2},{3,4}})`? At the moment, you are creating an `vector>`. Similarly, `a4` is an `array>`. – Ranoiaetep Nov 17 '22 at 04:21

0 Answers0