Modern C++ 变长参数的展开

// 变长参数模板和变长参数
// 部分 Code 来自《现代 C++ 教程:高速上手 C++11/14/17/20》,这里作为笔记记录。

#include <iostream>
#include <string>


// 变长参数解包:

/*************************/
/* Method 1: 递归模板函数 */
/*************************/
// 递归是非常容易想到的一种手段,也是最经典的处理方法。这种方法不断递归地向函数传递模板参
// 数,进而达到递归遍历所有模板参数的目的。
#ifdef __cpp_if_constexpr // or #if __cplusplus >= 201606L
template<typename T, typename... Args>
void printf1(T val, Args... args)
{
    std::cout << val << std::endl;
    if constexpr (sizeof...(args) > 0)  // for c++17
        printf1(args...);
}
#else
// c++17 之前,递归函数模板需要单独定义终止递归的函数,即只有一个参数的printf1
template<typename T>
void printf1(T val)
{
    std::cout << val << std::endl;
}

template<typename T, typename... Args>
void printf1(T val, Args... args)
{
    std::cout << val << std::endl;
    printf1(args...);
}
#endif
/*************************/
/* Method 2: 初始化列表展开 */
/*************************/
// 递归模板函数是一种标准的做法,但缺点显而易见的在于必须定义一个终止递归的函数。
// 这里介绍一种使用初始化列表展开的黑魔法。

template<typename T, typename... Args>
auto printf2(T value, Args... args) {
    std::cout << value << std::endl;
    std::initializer_list<T>{
        (
            [&args] {
                std::cout << args << std::endl;
            }(), 
            value
        )...
    };
}

/********************/
/* c++17 折叠表达式  */
/********************/
#ifdef __cpp_fold_expressions // or #if __cplusplus >= 201411L
template<typename ...Args>
auto sum(Args... args)
{
    // return (args + ...);  // for c++17
    return (... + args);     // same
}

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

#endif

int main()
{
    std::cout << "---\n";
    printf1(1);
    printf1(2, 3, "str", 1.2f);

    std::cout << "---\n";
    printf2<int, int, std::string>(1, 2, "hello");

#if __cplusplus >= 201411L // or #ifdef __cpp_fold_expressions
    std::cout << "---\n";
    std::cout << sum(2, 6, 5.5f) << std::endl;

    printer("cpp", ' ', 'a', ' ', 2.3f, ' ', 2);
#endif    
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值