如何用模板参数包的内容填充数组? [英] How to fill array with contents of a template parameter pack?

查看:65
本文介绍了如何用模板参数包的内容填充数组?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我发现它不符合标准之前,我已经嵌套了与VS 2015一起使用的部分专用模板代码。我希望如此,所以我扭曲了代码以克服前一个问题,并且那个现在已经遇到了困难。 / p>

使用可变参数模板和部分专业化,我想在给定固定参数集的情况下在编译时填充数组。



我想要实现的目标似乎也类似于此答案,但是我没有设法使它起作用。

p>

请考虑以下程序:

  #include< cstdlib> 

模板< typename T,std :: size_t Size>
结构数组;

模板< typename T,std :: size_t大小,std :: size_t迭代,类型名... Args>
struct ArrayFiller {
inline
static void fill(Array< T,Size>& a,const Args& ... args){
ArrayFiller< T,Size,Iteration ,Args ...> :: fill_recursive(a,args ...);
}

内联
静态void fill_recursive(Array< T,Size>& a,const T& i,const Args& ... args){
a.data [Size-Iteration-1] = i;
ArrayFiller< T,大小,迭代-1> :: fill_recursive(a,args ...);
}
};

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

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

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

int main(){
Array< int,2> c(42,-18);
返回0;
}

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

  main.cpp:在静态无效ArrayFiller< T,大小,迭代,Args> :: fill(Array< T,Size>& ;, const Args& ...)[带有T = int; long unsigned int大小= 2ul; long unsigned int迭代= 1ul; Args = {int,int}]':
main.cpp:34:54:需要'Array< T,Size> :: Array(const Args& ...)[with Args = {int,int }; T = int; long unsigned int Size = 2ul]'
main.cpp:39:28:从此处需要
main.cpp:10:65:错误:没有匹配函数可用于调用'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:注意:候选对象:static void ArrayFiller< T,Size,Iteration,Args> :: fill_recursive(Array< T,Size>&,const T& ;, const Args& ...)[with T = int; long unsigned int大小= 2ul; long unsigned int迭代= 1ul; Args = {int,int}]
static void fill_recursive(Array< T,Size>& a,const T& i,const Args& ... args){
^
main .cpp:14:17:注意:候选人需要4个参数,其中3个是

基本上,编译器抱怨没有匹配功能,因为根据我的理解,参数包在我的逻辑中扩展得太快或太晚: const T& i 递归调用中的参数弄乱了扩展。



您将如何解决?



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

解决方案

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

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

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


I had nested partially specialized template code working with VS 2015 until I discovered that it was not standards-compliant. I want it to be so I twisted my code to overcome the former issue and also that one and have now hit a hard wall.

Using variadic templates and partial specialization I would like to fill an array at compile-time given a fixed set of parameters.

What I want to achieve also seems similar to this answer but I did not manage to make it work.

Consider the following program:

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

...and the beginning of its g++ -std=c++14 -pedantic -Wall -Wextra output (as of version 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

Basically the compiler complains that there is no matching function because from what I understand the parameter pack is expanded either too "soon" or too "late" in my logic: the const T& i argument in the recursive call messes up the expansion.

How would you fix it?

I am also interested in alternate / better / cleaner solutions.

解决方案

Is a solution not based on template recursion acceptable in your use case? 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);
}

这篇关于如何用模板参数包的内容填充数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆