c++之说_13|模板 折叠表达式

折叠表达式 可以通过形参包的的实际参数(不是类型)  展开式子

c++之说_13|模板 折叠表达式_第1张图片

这是这里说的几种  实际上并还有一些写法

先介绍这几种吧

#include 
template
struct integer_sequence
{
  T val;
};
template
int get(_Tulp& t)
{
	
    return 0;
}
template
using b = Ret(*)(T...);
b _fun;

template
void getc(T...)
{
}

template
auto call(integer_sequence int_seq)
{
  T _tuple;
  
	//return getc((get(_tuple))...);
  //return getc(get(_tuple)...);
  //return ((get(_tuple),...));
  //return (ints||...);//一元右折叠
  //return (...,ints);//一元左折叠
 //return ((5*10)+...+ints);//二元左折叠
 //return (ints+...+(5*10));//二元右折叠
  
}
template
auto call(T* ... c)//integer_sequence int_seq)
{
 	//return (c -> h,...);
  	//return (*_fun)(c -> h...);
    return (*_fun)(	[&](){return c->h;  }()...);
  // return (c&&...&&0);
}
template
struct jk
{
  T h;
};

int main()
{
  	jk b;
  	b.h = 10;
   call(&b,&b,&b,&b);
  call(integer_sequence());
}

return (ints||...);//一元右折叠
  //return (...,ints);//一元左折叠
 // return ((5*10)+...+ints);//二元左折叠
  //return (ints+...+(5*10));//二元右折叠

调用处 call(integer_sequence());

我们先看一元右折叠

return (ints||...);//一元右折叠

template<>
bool call(integer_sequence int_seq)
{
  int _tuple;
  return static_cast(0) || (static_cast(1) || (static_cast(2) || static_cast(3)));
}
//实例化后是如此

0|| 
(  1 || (  2 || 3 ) 

) 

是的外围没有小括号了

一元左折叠

 return (...,ints);//一元左折叠


template<>
int call(integer_sequence int_seq)
{
  int _tuple;
  return ((0 , 1) , 2) , 3;
}
这个清楚多了

二元左折叠

return ((5*10)+...+ints);//二元左折叠

template<>
int call(integer_sequence int_seq)
{
  int _tuple;
  return ((((5 * 10) + 0) + 1) + 2) + 3;
}

二元右折叠

return (ints+...+(5*10));//二元右折叠

template<>
int call(integer_sequence int_seq)
{
  int _tuple;
  return 0 + (1 + (2 + (3 + (5 * 10))));
}

好了简单的折叠式子给了

现在我们来看看有点不一样的

----------------------------------------------------

return getc( ( get(_tuple) )... );

比如这里  我们能看出想法

要根据 形参包实际的参数 ints 去调用并 铺开成为 

函数 getc 的参数

ints = {0,1};

return getc( (get<0>(_tuple)) , ( get<1>(_tuple)) );

实际上展开呢?

call(integer_sequence());//调用处


template<>
void call(integer_sequence int_seq)
{
  int _tuple;
  return getc((get<0>(_tuple)), (get<1>(_tuple)), (get<2>(_tuple)), (get<3>(_tuple)));
}

这个和我们之前看到的规则有些不同  什么一元二元 没用到哇

你说括号好多?不和我们平时调用的一样

return getc(get(_tuple)...);


template<>
void call(integer_sequence int_seq)
{
  int _tuple;
  return getc(get<0>(_tuple), get<1>(_tuple), get<2>(_tuple), get<3>(_tuple));
}

如此更改  括号没了

这个可以说就是 把  ... 左边的 成一个整体  get(_tuple)

有前提  必须得是在  类似于函数参数中

 return (get(_tuple)...);
这样写很遗憾是错误的
我们只能使用
一元二元的规则

 return (get(_tuple),...);


template<>
int call(integer_sequence int_seq)
{
  int _tuple;
  return get<0>(_tuple) , (get<1>(_tuple) , (get<2>(_tuple) , get<3>(_tuple)));
}


如果这样
return ((get(_tuple),...));

template<>
int call(integer_sequence int_seq)
{
  int _tuple;
  return (get<0>(_tuple) , (get<1>(_tuple) , (get<2>(_tuple) , get<3>(_tuple))));
}

外部就会多个括号

-------------------------------------------------------------------------------------------------------------

jk b;
  	b.h = 10;
   call(&b,&b,&b,&b);
//调用处


template
auto call(T* ... c)//integer_sequence int_seq)
{
 	return (c -> h,...);
  	//return (*_fun)(c -> h...);
   // return (*_fun)(	[&](){return c->h;  }()...);
  // return (c&&...&&0);
}

我们还可以访问类的成员

template<>
int call, jk, jk, jk >(jk * __c0, jk * __c1, jk * __c2, jk * __c3)
{
  return __c0->h , (__c1->h , (__c2->h , __c3->h));
}

使用函数指针

template
using b = Ret(*)(T...);

b _fun;


return (*_fun)(c -> h...);


template<>
void call, jk, jk, jk >(jk * __c0, jk * __c1, jk * __c2, jk * __c3)
{
  return (*_fun)(__c0->h, __c1->h, __c2->h, __c3->h);
}

lambda函数

 return (*_fun)(	[&](){return c->h;  }()...);
template<>
void call, jk, jk, jk >(jk * __c0, jk * __c1, jk * __c2, jk * __c3)
{
      
  class __lambda_41_21
  {
    public: 
    inline /*constexpr */ int operator()() const
    {
      return __c0->h;
    }
    
    private: 
    jk & * __c0;
    
    public:
    __lambda_41_21(jk & * ___c0)
    : __c0{___c0}
    {}
    
  } __lambda_41_21{__c0};
  
    
  class __lambda_41_21
  {
    public: 
    inline /*constexpr */ int operator()() const
    {
      return __c1->h;
    }
    
    private: 
    jk & * __c1;
    
    public:
    __lambda_41_21(jk & * ___c1)
    : __c1{___c1}
    {}
    
  } __lambda_41_21{__c1};
  
    
  class __lambda_41_21
  {
    public: 
    inline /*constexpr */ int operator()() const
    {
      return __c2->h;
    }
    
    private: 
    jk & * __c2;
    
    public:
    __lambda_41_21(jk & * ___c2)
    : __c2{___c2}
    {}
    
  } __lambda_41_21{__c2};
  
    
  class __lambda_41_21
  {
    public: 
    inline /*constexpr */ int operator()() const
    {
      return __c3->h;
    }
    
    private: 
    jk & * __c3;
    
    public:
    __lambda_41_21(jk & * ___c3)
    : __c3{___c3}
    {}
    
  } __lambda_41_21{__c3};
  
 
return (*_fun)(__lambda_41_21.operator()(), __lambda_41_21.operator()(), __lambda_41_21.operator()(), __lambda_41_21.operator()());
 
大概就是这样
return (*_fun)(	[&](){return c->h;  }(),[&](){return c->h;  }(),[&](){return c->h;  }(),[&](){return c->h;  }());

从这里我们也可以看出 lambda 本质是是一个类里面

使用了 operator()

我现所知晓的折叠表达式已经说完了

你可能感兴趣的:(C++,c++,开发语言)