Home > Enterprise >  Initialization of a C-styled array (to the value 1) who's size is a template parameter
Initialization of a C-styled array (to the value 1) who's size is a template parameter

Time:04-29

// sz can only be 3 or 4
template<int sz>
void func() {
 int arr[sz]; 
}

I would like to initialize arr to be all ones without a loop. Is this possible to do? I'm envisioning something like

int arr[sz] = {1, 1, 1,...,1};

but for a variable sized array.

I think one approach is

int arr[sz] = (sz == 4) ? {1, 1, 1, 1} : {1, 1, 1};

CodePudding user response:

The other solutions work great and the suggestion of using std::array is definitely the best idea. If you want to allow more options you could revert to variadic templates:

#include <array>
#include <algorithm>
#include <iostream>
#include <iterator>

template<std::size_t... I>
constexpr auto ones_impl(std::index_sequence<I...>) {
    return std::array<int, sizeof...(I)>{ (I, 1)... };
}
template<std::size_t N>
constexpr auto ones() {
    return ones_impl(std::make_index_sequence<N>{});
}

template<int sz>
void func() {
    auto arr = ones<sz>();

    copy(arr.begin(), arr.end(), std::ostream_iterator<int>(std::cout, ", "));
    std::cout << '\n';
}

int main()
{
    std::cout << "funct<3>(): ";
    func<3>();
    std::cout << "funct<4>(): ";
    func<4>();
    std::cout << "funct<7>(): ";
    func<7>();
}

Due credit to this answer.

CodePudding user response:

This is much simpler if you use std::array, i.e. you can use the immediately invoke lambda to return the corresponding array based on the value of sz

// sz can only be 3 or 4
template<int sz>
void func() {
  std::array<int, sz> arr = []() -> std::array<int, sz> {
    if constexpr (sz == 4) 
      return {1, 1, 1, 1};
    else
      return {1, 1, 1};
  }();
}

Since C 17 guarantees copy elision, copy/move construction is not involved here.


C 14 solution

std::array<int, 3> 
gen_arr(std::integral_constant<int, 3>) {
  return {1, 1, 1};
}

std::array<int, 4> 
gen_arr(std::integral_constant<int, 4>) {
  return {1, 1, 1, 1};
}

// sz can only be 3 or 4
template<int sz>
void func() {
  std::array<int, sz> arr = gen_arr(std::integral_constant<int, sz>{});
}
  • Related