2017-02-09 28 views
5
#include <iostream> 
#include <string> 
#include <array> 

class C { 
private: 
    std::string a; 
    std::string b; 
    std::string c; 
public: 
    C(std::string a_, std::string b_, std::string c_) : a{a_},b{b_},c{c_} {} 
    ~C(){}; 
    C(const C&) =delete; 
    C(const C&&) =delete; 
    const C& operator=(const C&) =delete; 
    const C& operator=(const C&&) =delete; 
}; 

std::array<C,2> array = {C("","",""),C("","","")}; 

int main() 
{} 

điều này sẽ không biên dịch (Android Studio với NDK và clang) với lỗi "gọi tới hàm tạo bị lỗi c". Tôi biết rằng tôi có thể sử dụng std::vectoremplace_back() để tạo thành phần tử trực tiếp bên trong vùng chứa, nhưng trong mã của tôi, tôi chỉ muốn sử dụng các vùng chứa có kích thước cố định và các đối tượng không thể sao chép/di chuyển để tối ưu hóa. Tôi có thể thiếu sth cơ bản ở đây, nhưng không phải là có một cách để khởi tạo các std::array mà không cần phải xây dựng các yếu tố cá nhân và sau đó sao chép chúng ở đó?khởi tạo std :: mảng không có phần tử sao chép/di chuyển

+2

Bởi theo cách bạn không cần phải đặt những dấu gạch dưới trong tên tham số của bạn. 'C (std :: chuỗi a, std :: chuỗi b, std :: chuỗi c): a {a}, b {b}, c {c} {}' không có vấn đề mơ hồ và làm những gì bạn mong đợi. – nwp

Trả lời

6

Bạn có thể sử dụng cú đúp kèm initializers thay vì c đối tượng tạm thời:

std::array<c,2> array = {{{"",""},{"",""}}}; 

hoặc

std::array<c,2> array{{{"",""},{"",""}}}; 
+0

Đây có phải là giải pháp di động không? Tôi có nghĩa là nó phụ thuộc vào cách std :: mảng được thực hiện, nó phải chứa chính xác một phần tử của kiểu 'T [N]'. – marcinj

+0

@marcinj Tôi khá chắc chắn về nó. Thời gian qua tôi đã kiểm tra yêu cầu không phải là 'std :: array' chứa chính xác một phần tử của kiểu' T [N] ', nhưng nó hoạt động như thể nó đã làm. Có một vấn đề toàn bộ về việc liệu có thể bỏ qua phần giữa của '{}', tức là điều này cũng có hiệu lực không: '{{" "," "}, {" "," "}}'. Điều cuối cùng có thể đã thay đổi kể từ C++ 11. – juanchopanza

+0

Tôi hỏi vì tôi đã đọc một SO ở nơi T.C. nói rằng nó không được đảm bảo: http://stackoverflow.com/questions/27669200/how-should-i-brace-initialize-an-stdarray-of-stdpairs#comment43754338_27669457. – marcinj

5

Nó sẽ trở thành có thể từ C++ 17, từ đó đối với một số trường hợp quy định copy elision được đảm bảo .

Theo các trường hợp sau, các trình biên dịch được yêu cầu phải bỏ các copy- và nhà thầu move- của lớp đối tượng ngay cả khi sao chép/di chuyển constructor và destructor có thể quan sát được tác dụng phụ:

  • Khi khởi tạo, nếu biểu thức khởi tạo là giá trị và phiên bản cv-unqualified của loại nguồn giống với lớp của đích, biểu thức khởi tạo được sử dụng để khởi tạo đối tượng đích:

    T x = T(T(T())); // only one call to default constructor of T, to initialize x 
    

Và đối với những trường hợp này, constructor sao chép/di chuyển không cần thiết để có thể truy cập.

When copy-elision takes place (until C++17)In those cases where copy-elision is not guaranteed, if it takes place (since C++17) và các copy-/di chuyển-nhà xây dựng không được gọi, nó phải có mặt và truy cập (như thể không tối ưu hóa xảy ra ở tất cả), nếu không chương trình là vô hình thành.

LIVE

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