2012-12-19 14 views
9

thể trùng lặp:
C++11 emplace_back on vector<struct>?emplacing một POD

là emplacement thể với PODs? Dường như nó không hoạt động trong Visual Studio 2012:

struct X 
{ 
    int a; 
    int b; 
}; 

void whatever() 
{ 
    std::vector<X> xs; 
    X x = {1, 2}; 

    // okay 
    xs.push_back(x); 

    // okay 
    xs.emplace_back(x); 

    //error C2661: 'X::X': error C2661: no overloaded function takes 2 arguments 
    xs.emplace_back(1, 2); 
} 

Đây có phải chỉ là thiếu sót của Visual Studio 2012, hay không đặt POD đơn giản không hoạt động trong C++ 11?

+0

Nó xây dựng nó tại chỗ. Không có nhà xây dựng như thế. – chris

+0

Tôi sẽ không xem xét nó dứt khoát, nhưng g ++ (4.7.1) không chấp nhận nó. –

+0

Tôi nghĩ rằng bạn có thể phải có một hàm tạo cho 'X' có hai đối số (như thông báo lỗi gợi ý). –

Trả lời

5

Không có hàm tạo nào X::X(int,int), gọi hàm emplace_back của bạn để xây dựng đối tượng X là gì. Các thùng chứa sử dụng allocator_traits<A>::construct(allocator, p, args) để xây dựng các đối tượng, trong đó p là một con trỏ tới một số không gian được phân bổ và args là các đối số được truyền cho hàm tạo. Điều này được sử dụng bởi emplace_back. Cuộc gọi hàm construct này ::new((void*)p) T(std::forward<Args>(args)...), vì vậy nó không sử dụng khởi tạo đồng bộ.

xs.emplace_back({1, 2}) cũng sẽ là lỗi, mặc dù thực tế rằng tổng hợp có thể được tạo bằng danh sách khởi tạo. Đó là vì không thể chuyển tiếp danh sách bộ khởi tạo dấu ngoặc đơn.

+0

Sẽ hoạt động tốt với trình biên dịch tuân thủ, nhưng không phải với VC++ 2012 (chưa). : -] – ildjarn

+3

'emplace_back ({1, 2})' là một lỗi, 'push_back ({1, 2})' sẽ hoạt động. Việc khởi tạo danh sách không thể diễn ra trước đây vì không có gì để khởi tạo (nói không chính thức), đó là một điều ác cần thiết với việc khấu trừ đối số mẫu. –

+0

@LucDanton Cảm ơn, bạn nói đúng. –