4

As suspected, initializing std::pair with curly braces doesn't work because std::pair is not an aggregate.

std::pair <int, int> p = {1,2}; // Doesn't work

However, initializing an array of std::pair works well (with a warning in gcc 4.9)

std::pair <int, int> a_p[] = {
    {1,2},
    {3,4},
    {5,6}
}; // Works fine

Why is this happening?

EDIT: This question has been marked as a possible duplicate of C++11 aggregate initialization for classes with non-static member initializers However, this question does not talk about non-static-member-initializers, AFAIK, std::pair has a user defined constructor. Quoting from http://en.cppreference.com/w/cpp/header/utility,

template <class T1, class T2>
struct pair {
    typedef T1 first_type;
    typedef T2 second_type;

    T1 first;
    T2 second;
    pair(const pair&) = default;
    pair(pair&&) = default;

    constexpr pair();
    pair(const T1& x, const T2& y);
    template<class U, class V> pair(U&& x, V&& y);
    template<class U, class V> pair(const pair<U, V>& p);
    template<class U, class V> pair(pair<U, V>&& p);
    template <class... Args1, class... Args2>
        pair(piecewise_construct_t,
             tuple<Args1...> first_args, tuple<Args2...> second_args);

    pair& operator=(const pair& p);
    template<class U, class V> pair& operator=(const pair<U, V>& p);
    pair& operator=(pair&& p) noexcept(see below);
    template<class U, class V> pair& operator=(pair<U, V>&& p);

    void swap(pair& p) noexcept( noexcept(swap(first, p.first)) &&
                                 noexcept(swap(second, p.second)) );
};
Community
  • 1
  • 1
Mukul Gupta
  • 2,310
  • 3
  • 24
  • 39

1 Answers1

4

Aggregate-style initialization of class types ("uniform initialization") has been legal for the last 5 years, since C++11 was released.

Older versions of gcc default to the ancient C++03 standard (or the even older C++98), but are aware of C++11 so will under some circumstances apply C++11 rules where this is relatively unambiguous. This is the meaning of the warning:

warning: extended initializer lists only available with -std=c++11 or -std=gnu++11

Some even older versions of gcc may be applying their own (pre-C++11) extensions and so give different warnings.

You should compile in C++11 mode (at least), or use a modern compiler that defaults to C++11 or C++14, such as gcc 6.1.

ecatmur
  • 152,476
  • 27
  • 293
  • 366
  • Is aggregate initialization different from uniform initialization? `std::pair` has user defined constructors which makes it a non-aggregate. However, it can still be initialized using the aggregate syntax. – Mukul Gupta May 12 '16 at 20:08
  • @MukulGupta uniform initialization is the use of list-initialization syntax to initialize anything - primitives, aggregates, classes with user-defined constructors. The distinction between aggregates and classes with user-defined constructors is less relevant in more recent versions of C++. – ecatmur May 12 '16 at 20:32