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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.