2012-02-02 45 views
8

Tôi đang tìm một phương pháp để khởi tạo một cấu trúc phức tạp chứa vector trong một hàng.Khởi tạo một cấu trúc chứa vector

Ví dụ nếu tôi có cấu trúc này:

struct A{ 
    double x; 
    double y; 
}; 
struct B{ 
    double z; 
    double W; 
}; 
struct C{ 
    A a; 
    B b; 
}; 

tôi có thể khởi tạo C theo cách này: C c = {{0.0,0.1},{1.0,1.1}};

Nhưng những gì Nếu tôi phải khởi tạo một cấu trúc như thế này?

struct A{ 
    double x; 
    double y; 
}; 
struct B{ 
    vector<double> values; 
}; 
struct C{ 
    A a; 
    B b; 
}; 

tôi phải làm điều đó trong một hàng duy nhất bởi vì tôi muốn cho phép những người sử dụng ứng dụng của tôi để xác định trong một lĩnh vực đơn lẻ tất cả các giá trị ban đầu. Và tất nhiên, tôi thích một cách tiêu chuẩn để làm điều đó và không phải là một tùy chỉnh.

Cảm ơn!

+0

Làm thế nào để những người sử dụng xác định giá trị ban đầu? Nếu đó là một tập tin cấu hình htat bạn chỉ định định dạng, bạn có thể cho phép một lớp lót. Sau đó phân tích nó thành cấu trúc trong C++ của bạn bằng cách sử dụng nhiều hơn một dòng. –

Trả lời

9

Bạn có thể khởi C theo một cách rất giống trong C++ để trong C:

C c = {{0.3, 0.01}, {{14.2, 18.1, 0.0, 3.2}}}; 
+5

Miễn là trình biên dịch của bạn hỗ trợ cú pháp khởi tạo C++ 11. –

+0

Tôi không tin điều này hoạt động rất rộng rãi. Khởi tạo một 'vectơ' với một danh sách như thế yêu cầu C++ 11 – Managu

+3

@MikeSeymour - Vì câu hỏi không chỉ rõ một trình biên dịch, tôi cho rằng OP đã đặt câu hỏi về C++ theo quy định của tiêu chuẩn. – Mankarse

0

Bạn có thể làm điều này:

C obj = { { 0.0, 0.1f }, std::vector<double>(2, 0.0) }; 

Nhưng rõ ràng là nó không phải là lý tưởng vì tất cả các giá trị trong vector của bạn cần phải giống nhau.

+0

anh ta chỉ xác định rằng nó cần phải được khởi tạo, không được thiết lập. haha – L7ColWinters

-1
struct C { 
    A a; 
    B b; 
    C(double ta[2], vector<double> tb) { 
     a = A(ta[0],ta[1]); // or a.x = ta[0]; a.y = ta[1] 
     b = tb; 
    } 
}; 

sau đó bạn có thể khởi tạo với một cái gì đó giống như

C c = C({0.0, 0.1} , vector<double> bb(0.0,5)); 
+0

Điều này không hoạt động. Lỗi: Không cho phép nhập tên –

0

Câu hỏi đặt ra là làm thế nào để khởi tạo B trong ví dụ thứ hai?

Bạn không thể khởi tạo một vector như thế này:

std::vector<int> v = { 1, 2, 3 }; // doesn't work 

Bạn có thể làm điều này

int data[] = { 1, 2, 3 }; 
std::vector<int> v(&data[0], &data[0]+sizeof(data)/sizeof(data[0])); 

(có nhiều cách đẹp hơn để làm điều đó). Tuy nhiên, đó không phải là "một lớp lót".

này hoạt động và tôi đã thử nghiệm nó:

template< typename T > 
struct vector_builder 
{ 
    mutable std::vector<T> v; 
    operator std::vector<T>() const { return v; } 
}; 

template< typename T, typename U > 
vector_builder<T>& operator,(vector_builder<T>& vb, U const & u) 
{ 
vb.v.push_back(u); 
return vb; 
} 

struct B 
{ 
    vector<double> v; 

}; 

B b = { (vector_builder(),1.1,2.2,3.3,4.4) }; 

C c = { {1.1, 2.2 }, {(vector_builder(),1.1,2.2,3.3,4.4)} }; 
0

Bạn sẽ chỉ phải sử dụng one of the constructors nếu bạn không có cú pháp khởi tạo mới C++ 11.

C c = {{1.0, 1.0}, {std::vector<double>(100)}}; 

Vectơ trên có 100 phần tử. Không có cách nào để khởi tạo từng phần tử duy nhất trong cấu trúc của vectơ.

Bạn có thể làm ...

double values[] = {1, 2, 3, 4, 5}; 
C c = {{1.0, 1.0}, {std::vector<double>(values, values+5)}}; 

hoặc nếu bạn luôn biết số phần tử sử dụng một std :: mảng mà bạn có thể khởi tạo theo cách bạn muốn.

3

Nếu bạn không sử dụng C++ 11 (do đó bạn không thể sử dụng gợi ý Mankarse của), tăng có thể giúp:

C c = { {0.1, 0.2}, {boost::assign::list_of(1.0)(2.0)(3.0)} }; 
Các vấn đề liên quan