c++templatesvariadic-templatesfold-expressionpack-expansion

How to pack variadic arguments of a template function into an array?


How to pack variadic arguments of the function into an array and return it from that function? All the arguments are of the same type.

Here's what I try to do, but it only seems to set the very first element of the array and rest of the elements are zero. So that's no good.

template<typename... T>
inline auto CreateArray(const T... t)
{
    constexpr int ELEMENT_COUNT = TotalElementCount(t...);

    return std::array<int, ELEMENT_COUNT>{ (t, ...) };
}

So if I run the following code:

    auto new_array = CreateArray(1, 2, 3, 4);

    for (auto x : new_array)
        std::cout << std::dec << x << std::endl;

I'll get the result:

4
0
0
0

What's wrong with my code?


Solution

  • What you want here is not a fold expression but a pack expansion:

    template <typename... T>
    inline auto CreateArray(const T... t) {
        constexpr auto ELEMENT_COUNT = sizeof...(t);
    
        return std::array<int, ELEMENT_COUNT>{t...};
    //                                       ^^^^^^
    }
    

    A perfect forwarding version:

    template <typename... T>
    inline auto CreateArray(T&&... t) {
        constexpr auto ELEMENT_COUNT = sizeof...(t);
    
        return std::array<int, ELEMENT_COUNT>{std::forward<T>(t)...};
    }
    

    You may also want to replace the value type int in the array with std::common_type_t<T...> to allow for the creation of non-int arrays.