c++ - 如何用模板参数包的内容填充数组?

标签 c++ recursion c++14 variadic-templates compile-time

在我发现 it was not standards-compliant 之前,我嵌套了与 VS 2015 一起使用的部分专用模板代码。 .我希望它是这样的,所以我扭曲了我的代码来克服前一个问题以及 that one现在碰壁了。

使用可变参数模板和部分特化,我想在编译时给定一组固定参数来填充一个数组。

我想要实现的目标似乎也类似于 this answer但我没能成功。

考虑以下程序:

#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;
}

...及其 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

基本上,编译器会提示没有匹配的函数,因为据我所知,参数包在我的逻辑中扩展得太“快”或太“晚”: const T& i 中的参数递归调用打乱了扩展。

您将如何修复它?

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

最佳答案

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

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

关于c++ - 如何用模板参数包的内容填充数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39169965/

相关文章:

C++ vector<vector<double>> 加倍 **

c++ - 从派生类中的模板化基类使用 typedef/using

recursion - 条件和递归

c++ - 为什么我不能按值将右值 std::stringstream 传递给函数?

c++ - 试图在递归函数 : Unhandled exception/Stack overflow 中捕获失败的分配

c++ - 使用 int vector 元素作为输入的递归方法类

c++ - 从模板参数中获取函数参数

c++ - 使用可变参数包实例化函数模板

c++ - 命名 union 的原因是什么?

python - Openmesh:使用 Python 更新面法线比使用 C++ 更快?