2014-07-03 16 views
5

tôi có một std::vector<std::vector<double>> và muốn thêm một số yếu tố ở phần cuối của nó vì vậy đây là thử nghiệm của tôi:emplacement của một vector với danh sách initializer

std::vector<std::vector<double> > vec; 
vec.emplace_back({0,0}); 

nhưng điều này không biên dịch trong khi sau đây sẽ làm:

std::vector<double> vector({0,0}); 

Tại sao emplace_back không thể xây dựng phần tử ở vị trí này? Hay tôi đang làm gì sai?

Cảm ơn sự giúp đỡ của bạn.

Trả lời

7

Việc khấu trừ mẫu không thể đoán rằng danh sách khởi tạo đính kèm ngoặc đơn phải là một vectơ. Bạn cần phải rõ ràng:

vec.emplace_back(std::vector<double>{0.,0.}); 
+0

cảm ơn, nhưng tôi có một câu hỏi như thế này: Tại sao nó làm việc cho ví dụ thứ hai? Vì trình biên dịch có thông tin tương tự về kiểu (emplace_back sẽ lấy đối số cho một hàm tạo của std :: vector và ví dụ thứ hai) – m47h

+0

Vì trong ví dụ thứ hai, bạn gọi hàm tạo của vectơ, có thể xử lý danh sách khởi tạo trực tiếp. – marli

+3

Vì vậy, bạn không tạo được hiệu quả, nhưng chỉ cần đẩy một phần tử đã được xây dựng, thay vì xây dựng vectơ tại chỗ. –

6

Câu trả lời trước đây đề cập bạn có thể lấy mã để biên dịch khi bạn tạo vectơ thẳng hàng và đặt nó vào. Điều đó có nghĩa, tuy nhiên, bạn đang gọi di chuyển-nhà xây dựng trên một vector tạm thời, có nghĩa là bạn không phải xây dựng các vector tại chỗ, trong khi đó là toàn bộ lý do sử dụng emplace_back thay vì push_back.

Thay vào đó bạn nên bỏ danh sách initializer một initializer_list, như vậy:

#include <vector> 
#include <initializer_list> 

int main() 
{ 
    std::vector<std::vector<int>> vec; 
    vec.emplace_back((std::initializer_list<int>){1,2}); 
} 
+0

Nó thực sự sẽ gọi hàm khởi tạo, chứ không phải hàm tạo bản sao. – Arcinde

+0

Bắt tốt. Đã chỉnh sửa câu trả lời của tôi. –

+0

Tại sao bạn sử dụng cú pháp C-cast kiểu cũ '(std :: initializer_list ) {1,2}' ở đây thay vì cú pháp hàm tạo 'std :: initializer_list ({1,2})'? – Peter

Các vấn đề liên quan