c – 为什么在迭代可变参数模板参数时我们必须使用额外的构造?
发布时间:2020-12-16 10:36:56  所属栏目:百科  来源:网络整理 
            导读:为什么在迭代可变参数模板参数时,我们必须使用其他构造,如(non() – function,temp [] – array或empty [](…){} – lambda)? 众所周知,我们可以通过以下方式使用C中的可变参数模板迭代参数包: http://ideone.com/GXDPDw #include iostream#include cstdli
                
                
                
            | 
 为什么在迭代可变参数模板参数时,我们必须使用其他构造,如(non() – function,temp [] – array或empty [](…){} – lambda)? 
  
  众所周知,我们可以通过以下方式使用C中的可变参数模板迭代参数包: http://ideone.com/GXDPDw #include <iostream>
#include <cstdlib>
#include <valarray>
#include <numeric>
using namespace std;
template<typename ...Args> constexpr inline void non(Args ...) {}
template<typename T,typename ...Args>
inline T sum1(T val,Args ...args) { non(val += args ...); return val; }   // v1
// why do we need some function non() here?
template<typename T,typename ...Args>
inline T sum2(T val,Args ...args) { auto tmp = { val += args... }; return val; }   // v2
// why do we need some array tmp[] here?
template<typename T,typename ...Args>
inline T sum3(T val,Args ...args) { [](...){}((val += args)... ); return val; }   // v3
// why do we need empty lambda [](...){} here?
template<typename T,typename ...Args>
inline T sum4(T val,Args ...args) { for(auto &i:{ args... }) val += i; return val; }//v4
template<typename ...Args,typename T = common_type_t<Args...>>
inline T sum5(Args ...args) { return std::valarray<T>({ args... }).sum(); }   // v5
template<typename T> constexpr inline T sum6(T val) { return val; }
template<typename T,typename ...Args>
constexpr inline T sum6(T val,Args ...args) { return val + sum6(args...); }  // v6
int main() {    
    cout << sum1(1,2,3) << endl;
    cout << sum2(1,3) << endl;
    cout << sum3(1,3) << endl;
    cout << sum4(1,3) << endl;
    cout << sum5(1,3) << endl;
    cout << sum6(1,3) << endl;
    return 0;
}但为什么我们需要使用: > non(val = args …);而不是val = args …; 它会更清晰,更容易使用: template<typename T,typename ...Args>
inline T sum(T val,Args ...args) { val += args...; return val; }为什么标准中没有这种可能性,或者这种可能性是否会带来任何危险? 在C 17或更高版本中会出现这种可能吗? 解决方法
 这是因为必须在需要语法列表的上下文中扩展参数包.正常的函数范围不是这样的上下文,所以你不能只写val = args … ;. 
  
  但是,在C 17中,我们将获得fold expressions,这将允许您重写代码,如下所示: template<typename T,Args ...args) { (val += ... += args) ; return val; }对于三个参数,这将扩展为(((val = arg0))= arg1)= arg2). 另一种选择是这样写: val += (... + args); 这扩展为val =((arg0 arg1)arg2) 折叠表达式还支持扩展涉及参数包的任意表达式,如下所示: (foo(args),...); ((mymap[args] = 42),...); 这使您能够轻松地在功能范围内使用参数包扩展表达式. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! | 
