2016-05-12 3 views
1

Как и предполагалось, инициализация std::pair с фигурными фигурными скобками не работает, потому что std::pair не является совокупностью.Агрегатная инициализация для массива std :: pair

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

Однако, инициализация массива std::pair хорошо работает (с предупреждением в gcc 4.9)

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

Почему это происходит?

EDIT: Этот вопрос был отмечен как возможный дубликат C++11 aggregate initialization for classes with non-static member initializers Однако этот вопрос не говорит о нестатических-членах-инициализаторах, AFAIK, std::pair имеет определенный пользователем конструктор. Цитируя 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))); 
}; 

ответ

3

инициализация агрегированного стиль типов классов («равномерная инициализация») была законной в течение последних 5 лет, так как C++ 11 было выпущено.

Старые версии gcc по умолчанию для древнего стандарта C++ 03 (или даже старше C++ 98), но знают о C++ 11, поэтому в некоторых случаях применяются правила C++ 11, где это относительно однозначно. Это значение предупреждения:

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

Некоторые даже более старые версии GCC могут применять свои собственные методы (Pre-C++ 11) расширения и поэтому дают различные предупреждения.

Вы должны скомпилировать в режиме C++ 11 (по крайней мере) или использовать современный компилятор, который по умолчанию использует C++ 11 или C++ 14, например gcc 6.1.

+0

Является ли агрегатная инициализация отличной от равномерной инициализации? 'std :: pair' имеет пользовательские конструкторы, которые делают его неагрегатным. Однако его можно инициализировать, используя синтаксис агрегата. –

+0

Единая инициализация @MukulGupta - это использование синтаксиса инициализации списка для инициализации - примитивы, агрегаты, классы с определенными пользователем конструкторами. Различие между агрегатами и классами с определенными пользователем конструкторами менее актуально в более поздних версиях C++. – ecatmur

Смежные вопросы