如何使用模板参数包的内容填充数组?

dum*_*dev 4 c++ recursion compile-time variadic-templates c++14

我已经嵌套了与VS 2015一起使用的部分专用模板代码,直到我发现它不符合标准.我希望它是如此,所以我扭曲了我的代码来克服前一个问题,而且那个问题现在已经发生了变化.

使用可变参数模板和部分特化我想在给定一组固定参数的情况下在编译时填充数组.

我想要达到的目标似乎与这个答案相似,但我没有设法让它发挥作用.

考虑以下程序:

#include <cstdlib>

template <typename T, std::size_t Size>
struct Array;

template <typename T, std::size_t Size, std::size_t Iteration, typename ...Args>
struct ArrayFiller {
    inline
    static void fill(Array<T, Size>& a, const Args&... args) {
        ArrayFiller<T, Size, Iteration, Args...>::fill_recursive(a, args...);
    }

    inline
    static void fill_recursive(Array<T, Size>& a, const T& i, const Args&... args) {
        a.data[Size - Iteration - 1] = i;
        ArrayFiller<T, Size, Iteration - 1>::fill_recursive(a, args...);
    }
};

template <typename T, std::size_t Size>
struct ArrayFiller<T, Size, 0> {
    inline
    static void fill_recursive(Array<T, Size>& a, const T& i) {
        a.data[Size - 1] = i;
    }
};

template <typename T, std::size_t Size>
struct Array {
    T data[Size];

    template <typename ...Args>
    Array(const Args&... args) {
        ArrayFiller<T, Size, Size - 1, Args...>::fill(*this, args...);
    }
};

int main() {
    Array<int, 2> c(42, -18);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

...及其g++ -std=c++14 -pedantic -Wall -Wextra输出的开头(从5.3.0版开始):

main.cpp: In instantiation of ‘static void ArrayFiller<T, Size, Iteration, Args>::fill(Array<T, Size>&, const Args& ...) [with T = int; long unsigned int Size = 2ul; long unsigned int Iteration = 1ul; Args = {int, int}]’:
main.cpp:34:54:   required from ‘Array<T, Size>::Array(const Args& ...) [with Args = {int, int}; T = int; long unsigned int Size = 2ul]’
main.cpp:39:28:   required from here
main.cpp:10:65: error: no matching function for call to ‘ArrayFiller<int, 2ul, 1ul, int, int>::fill_recursive(Array<int, 2ul>&, const int&, const int&)’
         ArrayFiller<T, Size, Iteration, Args...>::fill_recursive(a, args...);
                                                                 ^
main.cpp:14:17: note: candidate: static void ArrayFiller<T, Size, Iteration, Args>::fill_recursive(Array<T, Size>&, const T&, const Args& ...) [with T = int; long unsigned int Size = 2ul; long unsigned int Iteration = 1ul; Args = {int, int}]
     static void fill_recursive(Array<T, Size>& a, const T& i, const Args&... args) {
                 ^
main.cpp:14:17: note:   candidate expects 4 arguments, 3 provided
Run Code Online (Sandbox Code Playgroud)

基本上编译器抱怨没有匹配的函数,因为从我的理解,参数包在我的逻辑中"太快"或太"太晚" const T& i扩展:递归调用中的参数扰乱了扩展.

你会怎么解决它?

我也对替代/更好/更清洁的解决方案感兴趣.

Vit*_*meo 11

是不是基于您的用例中可接受的模板递归的解决方案?wandbox链接

template <typename T, std::size_t Size>
struct Array {
    T data[Size];

    template <typename ...Args>
    constexpr Array(const Args&... args) : data{args...} {

    }
};

int main() {
    Array<int, 2> c(42, -18);
    assert(c.data[0] == 42);
    assert(c.data[1] == -18);

    constexpr Array<int, 2> cc(42, -18);
    static_assert(cc.data[0] == 42);
    static_assert(cc.data[1] == -18);
}
Run Code Online (Sandbox Code Playgroud)