// 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>{});
}