折叠表达式

折叠表达式

一元左折,一元右折

namespace detail1
{
    // 一元左折
    template <typename... T>
    auto add_val(T... args)
    {
        return (... + args);
    }
    template <typename... T>
    auto add_val2(T... args)
    {
        return (... - args);
    }
    // 一元右折
    template <typename... T>
    auto add_val3(T... args)
    {
        return (args + ...);
    }
    template <typename... T>
    auto add_val4(T... args)
    {
        return (args - ...);
    }

}
   cout << "一元左折" << endl;
    // 一元左折 (unary leftfold)
    //  格式:(... 运算符 一包参数)
    cout << detail1::add_val(10, 20, 30, 40); // (((10+20)+30)+40)
    endl(cout);
    cout << detail1::add_val2(10, 20, 30, 40); //(((10-20) -30)-40)
    endl(cout);

    cout << "一元右折" << endl;
    // 一元右折 (unary leftfold)
    //  格式:(  一包参数  运算符    ...)
    cout << detail1::add_val3(10, 20, 30, 40); // (((40+30)+20)+10)
    endl(cout);
    cout << detail1::add_val4(10, 20, 30, 40); // (((40-30)-20)-10)
    endl(cout);

二元左折,二元右折

namespace detail2
{
    // 二元左折
    template <typename... T>
    auto add_val(T... args)
    {
        return (100 + ... + args);
    }
    template <typename... T>
    auto add_val2(T... args)
    {
        return (100 - ... - args);
    }
    // 一元右折
    template <typename... T>
    auto add_val3(T... args)
    {
        return (args + ... + 100);
    }
    template <typename... T>
    auto add_val4(T... args)
    {
        return (args - ... - 100);
    }
    template <typename... T>
    void add_val5(T... args)
    {
        (cout << ... << args);
    }
}
cout << "二元左折" << endl;
    // 二元左折

    //  格式:( init 运算符 ... 运算符 一包参数)

    // init 表示一个初始的东西,它可能是一个值,也可能是个其他东西。
    cout << detail2::add_val(10, 20, 30, 40); //((((100+10) +20)+30)+40)
    endl(cout);
    cout << detail2::add_val2(10, 20, 30, 40); // ((((100 - 10) - 20) - 30) - 40)
    endl(cout);

    cout << "二元右折" << endl;
    // 二元右折 (unary leftfold)
    //  格式:(  一包参数  运算符    ... 运算符  init)
    // init 表示一个初始的东西,它可能是一个值,也可能是个其他东西。
    // 当init 是一个值时
    cout << detail2::add_val3(10, 20, 30, 40); // ((((40+30)+20)+10)+100)
    endl(cout);
    cout << detail2::add_val4(10, 20, 30, 40); //(10-(20- (30-(40-100))))
    endl(cout);
    // 当init 不是一个值,而是一个对象
    detail2::add_val5(10, 20, 30, 40, " casdcsad ", "sdvsdvsdv"); // 10203040 casdcsad sdvsdvsdv *
    // cout<<10<<20    cout 是对象 也就是init ,<< 是运算符 ,cout<<10 返回的是cout 对象

可变参表达式

namespace detail3
{
    template <typename... Types>
    void print(Types const &...args)
    {
        (std::cout << ... << args) << endl;
    }
    // todo  对参数包中所有的参数进行计算,将参数包中的所有的参数都翻倍,然后将结果传给 print()
    template <typename... T>
    void printDoubled(T const &...args)
    {
        print(args + args...);
    }

    // todo 对参数包中的每一个参数+1
    template <typename... T>
    void addOne(T const &...args)
    {
        // print(args + 1...); // ERROR: 1... is a literal with too many decimal points
        // print(args + 1 ...);  // OK
        print((args + 1)...); // OK
    }
}
// 调用
    detail3::printDoubled(7.5, std::string("hello"), std::complex<float>(4, 2));

    // 等效于调用
    // print(7.5+7.5,
    //       std::string("hello") + std::string("hello"),
    //       std::complex<float>(4,2) + std::complex<float>(4,2));
    detail3::addOne(11, 10, 12, 14, 15);

简化打印参数

同样也可以用该方法简化可变参数模板来打印参数:

template<typename... Types>
void print (Types const&... args)
{
    (std::cout << ... << args) << '\n';
}

如果需要在元素间添加空格,需要额外的类模板:

// basics/addspace.hpp

template<typename T>
class AddSpace
{
private:
    T const& ref; // refer to argument passed in constructor
public:
    AddSpace(T const& r): ref(r) {
    }
    friend std::ostream& operator<< (std::ostream& os, AddSpace<T> s) {
       return os << s.ref << ' '; // output passed argument add a space
    }
};

template<typename... Args>
void print (Args... args){
    (std::cout << ... << AddSpace(args) ) << '\n';
}

此例子中,AddSpace(args)使用类模板实参推导,有AddSpace<Args>(args)的作用,对于每一个实参创建一个AddSpace的实例。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

丁金金

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值