#cpp #gcc #x86_64
Елементарный способ: произвести заполнение массива при инициализации. Но массив статический и уже занимает место в образе. Нужно каким-то образом указать компилятору заполнить область массива конкретным значением. Код static int arr[5]={1} заполняется как {1, 0, 0, 0, 0}, а нужно {1, 1, 1, 1, 1} __attribute__((fillupper(1))) игнорируется gcc. Массив неконстантный. Массив с 5 элементами - пример. Нужно заполнить массив в 4096 элементов. Использование возможностей STL сильно ограничены, включая производные. Они все имеют элементарное решение, указанное в первом предложении. Доработка ответа: templatestruct IArray { type val = v; IArray& operator=(type n){ val=n; return *this; } IArray& operator|=(type n){ val|=n; return *this; } }; И необходимо дописать/изменить операторы для нужных Вам преобразований.
Ответы
Ответ 1
#includetemplate struct Int { int val = v; }; int main() { Int<10> arr[1024]; std::cout << arr[10].val << std::endl; } https://godbolt.org/z/6-BEPi Ответ 2
Не бейте меня. Нашёл только asm способ. //> g++ -std=c++11 memset.cpp #includeasm( " .globl s2\n" " .data\n" " .align 32\n" " .type s2, @object\n" " .size s2, 16384\n" "s2: .fill 4096,4,777\n" ); extern "C" { extern int s2[4096]; }; int main(){ for(size_t j = 4096+1;j>0;){--j; std::cout<<"s2["< g++ -std=c++11 -S memset.cpp #include int main(){ int m[4096]{}; int n[4096]; memset(n,1,4096); } Результатом будет код: subq $32768, %rsp leaq -32768(%rbp), %rax movl $16384, %edx movl $0, %esi movq %rax, %rdi call memset leaq -16384(%rbp), %rax movl $4096, %edx movl $1, %esi movq %rax, %rdi call memset Как видите, никакой разницы , только 0 и 1 . Ответ 3
GCC поддерживает нестандартный синтаксис static int arr[4096] = { [0 ... 4095] = 1 }; Но это расширение возможностей designated initializers, т.е. это С, а не С++. То есть можно, если устроит такой вариант, сделать в С++ проекте отдельный С-файл с int arr[4096] = { [0 ... 4095] = 1 }; а в С++ коде уже добавить extern "C" int arr[4096]; если вы готовы пожертвовать static.Ответ 4
dd if=/dev/zero of=/tmp/sarr conv=swab count=4096 xxd -i /tmp/sarr | sed -e 's/0x00/0x01/g' > /tmp/parr.h P.S. :) UPD: #includetemplate class ct_array { public: constexpr explicit ct_array(); public: const T& operator[](size_t idx) const; protected: T m_data[N]; }; template constexpr ct_array ::ct_array() : m_data() { for (T *el = m_data; el != m_data + N; ++el) *el = def_val; } template const T& ct_array ::operator[](size_t idx) const { return m_data[idx]; } template constexpr decltype(auto) make_ct_array() { return ct_array (); } int main() { constexpr auto arr = make_ct_array (); std::cout << arr[10] << std::endl; return 0; } UPD2: #include template class ct_array { public: constexpr explicit ct_array(T def); public: const T& operator[](size_t idx) const; protected: T m_data[N]; }; template constexpr ct_array ::ct_array(T def) : m_data() { for (T *el = m_data; el != m_data + N; ++el) *el = def; } template const T& ct_array ::operator[](size_t idx) const { return m_data[idx]; } template constexpr decltype(auto) make_ct_array(T def) { return ct_array (def); } int main() { constexpr auto arr = make_ct_array (3.14); std::cout << arr[10] << std::endl; return 0; } Ответ 5
Можно написать функцию templatevoid f(T a[], size_t s, const T& n) { for (size_t i = 0; i < s; ++i) a[i] = n; } Тогда const int n = 4096; int arr[n]; f(arr, n, 1); после ее вызова вы получите желаемый результат Или же воспользоваться стандартным альгоритмом const int n = 4096; int arr[n]; std::fill(arr, arr + n, 1);
Комментариев нет:
Отправить комментарий