2017-06-05 29 views
15

tôi cần một cách để khởi tạo các phần tử const của một mảng cho chương trình mà tôi hiện đang làm việc. Vấn đề là tôi phải khởi tạo các yếu tố này với một chức năng, không có cách nào để làm điều đó như thế này:C++ cách khởi tạo các phần tử const của một mảng

const int array[255] = {1, 1278632, 188, ...}; 

vì rất nhiều của dữ liệu tôi có để tạo ra. Những gì tôi đã thử là để memcpy dữ liệu vào const int nhưng không thể hoạt động và không hoạt động.

const int array[255]; 

void generateData(){ 
     for(int i = 0; i < 255; i++) { 
      initializeSomehowTo(5, array[i]); 
     } 
} 

Tôi hy vọng bạn hiểu những gì tôi đang cố gắng, xin lỗi nếu tôi tăng gấp đôi câu hỏi, tôi phải bỏ qua nó.

+5

Bạn không thể làm 'mảng int const [255] = initializeMyArray()', nhưng nếu bạn sử dụng 'std :: array', bạn có thể làm 'std :: const mảng = initializeMyArray()' – Justin

Trả lời

17

Làm thế nào về điều này?

#include <array> 
typedef std::array<int, 255> Array; 

const Array array = generateData(); 

Array generateData(){ 
    Array a; 
    for(int i = 0; i < a.size(); i++) { 
     initializeSomehowTo(a[i]); 
    } 
    return a; 
} 
+0

công trình này tuyệt vời, chỉ có điều là ** const int mảng [10] [10] [10]; ** trông thực sự đáng sợ: ** const std :: mảng , 10 >, 10> Array; ** ;-) – Tsoj

6

Phương pháp đơn giản nhất là để có được những mảng điền từ một chức năng và sử dụng để khởi tạo đối tượng const (hoặc constexpr) của bạn. Tuy nhiên, mảng built-in không thể sao chép nhưng std::array<T, N> là:

std::array<T, 255> array = initializeData(); 

Nếu bạn cần một mảng built-in, tôi có thể tưởng tượng được khởi tạo thành viên static của một lớp (mẫu, thực sự), nơi chỉ số này mở rộng từ chỉ số mở rộng từ một std::make_index_sequence<255> và sử dụng như là đối số vị trí trong mảng, tức là một cái gì đó dọc theo những dòng:

#include <algorithm> 
#include <iostream> 
#include <iterator> 
#include <utility> 

int some_function(std::size_t i) { return i; } 

template <typename> struct initialized_array_base; 
template <std::size_t... I> 
struct initialized_array_base<std::index_sequence<I...>> { 
    static const int array[sizeof...(I)]; 
}; 

template <std::size_t... I> 
int const initialized_array_base<std::index_sequence<I...>>::array[sizeof...(I)] 
    = { some_function(I)... }; 

struct initialized_array 
    :initialized_array_base<std::make_index_sequence<256>> { 
}; 

int main() { 
    std::copy(std::begin(initialized_array::array), 
       std::end(initialized_array::array), 
       std::ostream_iterator<int>(std::cout, " ")); 
    std::cout << '\n'; 
} 
+4

Wow có vẻ đáng sợ đối với một nhiệm vụ đơn giản như vậy ;-) – zett42

3

Bạn có thể tạo một mảng ghi, khởi tạo nó, và, sau đó, tạo một tham chiếu const để nó .

int arry[255]; 

void generateData(){ 
    for(int i = 0; i < 255; i++) { 
     initializeSomehowTo(5, arry[i]); 
    } 
} 

const int (&array)[255] = arry; 
+0

Điều này không ngăn chặn 'arry' bị sửa đổi, phải không? – Arun

+0

Tôi nghĩ bạn cũng có thể std :: static_cast để tham chiếu const –

+0

Mức bổ sung của indirection (đối với biến tham chiếu cũng có bộ nhớ tĩnh) có thể không tối ưu hóa. ** Tôi chắc chắn sẽ khuyên bạn không nên sử dụng ** này, vì trả về một 'std :: array <>' từ một hàm khởi tạo để tránh bất kỳ nhược điểm nào về hiệu suất. –

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