2016-05-12 1013 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 

這究竟是爲什麼?

編輯:這個問題已經被標記爲的可能重複C++11 aggregate initialization for classes with non-static member initializers 但是,這個問題並沒有談非靜態成員的初始化,據我所知,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可能會應用自己的(預C++ 11)擴展等給出不同的警告。

您應該用C++ 11模式(至少)編譯,或者使用默認爲C++ 11或C++ 14的現代編譯器,如gcc 6.1。

+0

聚集初始化與統一初始化不同嗎? 'std :: pair'具有用戶定義的構造函數,這使得它成爲非聚合函數。但是,它仍然可以使用聚合語法進行初始化。 –

+0

@MukulGupta統一初始化是使用列表初始化語法來初始化任何東西 - 包含用戶定義的構造函數的基元,聚集,類。使用用戶定義的構造函數的聚集和類之間的區別在更新版本的C++中不太相關。 – ecatmur