1

I have an std::array and I have a variadic template function with the number of parameters that matches the size of the array. I need to assign the arguments to the elements of the array. In other words, in the code below I wish a to get values {1, 2, 3} and b to get values {1, 2, 3, 4, 5}

std::array<int, 3> a;
std::array<int, 5> b;

assign_values(a, 1, 2, 3);
assign_values(b, 1, 2, 3, 4, 5);

The question is how to implement the assign_values variadic template function.

I'm limited with the C++14 version.

Update: The arguments can be of different types: assign_values(b, 1, 2u, 3., '4', 5l);

3
  • I'm confused: why is this tagged C++11 if you can use C++14? Commented Oct 29, 2019 at 0:08
  • @Chipster that just means that I can use C++11 but cannot use C++17. There is nothing in my question specific to C++14. Commented Oct 29, 2019 at 0:25
  • Got you. My thing though is since most C++ versions are backwards compatible, wouldn't it be best to put the most recent version you could use as a tag? That's just my thought process. You certainly don't have to tag it that way, though. Commented Oct 29, 2019 at 0:31

2 Answers 2

3

Sth like this:

template<class T, size_t N, class ... Values>
void assign_values(std::array<T,N>& arr, Values... vals) {
    static_assert(N == sizeof...(vals));
    int j = 0;
    for (auto i : std::initializer_list< std::common_type_t<Values...> >{vals...})
        arr[j++] = i;
}

Demo

Sign up to request clarification or add additional context in comments.

7 Comments

Or even `void assign_values(std::array<int,N>& arr, Values... vals) { arr = {vals...}; }
@Kit. yep, also your solution is nicer and simpler :)
@rafix07 This solution is not generic. You provide generic types Values but iterate just integers: for (int i : {vals...})
@rafix07 One more complication: in your snippet all Values are integers (at least they are of the same type). What if we use different types (even those that doesn't loose precision)? assign_values(b, 1, 2u, 3., '4');
@DmitryKuzminov initializer list must have all values with one type. So you can use common_type_t to deduce it. Then you can mix float, integers, chars in input parameter pack.
|
1

I'm limited with the C++14 version

The good old trick of the unused array initialization (pre C++17 surrogate of template folding) should works (also C++11)

template <typename T, std::size_t N, typename ... Values>
void assign_values (std::array<T,N> & arr, Values... vals)
 {
    static_assert(N == sizeof...(vals));

    using unused = int[];

    int j = 0;

    (void)unused { 0, (arr[j++] = vals, 0)... };
 }

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.