首页 > 其他分享 >模板

模板

时间:2024-09-07 19:36:50浏览次数:8  
标签:std ... args 参数 template 类型 模板

模板

可变参数模板

可变参数模板(Variadic Templates)是C++11引入的一种强大特性,它允许模板接受可变数量的模板参数或函数参数。可变参数模板为编写通用性更强的代码提供了极大的灵活性,特别是在处理多种类型或不确定数量的参数时。

  • 模板参数包
    • 定义template<typename... Args> 中的 Args... 表示一个模板参数包(template parameter pack),它可以容纳零个或多个类型参数。
    • 展开Args... 表示对参数包的展开,通常在函数定义或调用时使用。
  • 函数参数包
    • 定义void func(Args... args) 中的 args... 是一个函数参数包(function parameter pack),表示可以接受零个或多个函数参数。
    • 展开args... 可以在函数体内展开,用于递归调用、初始化列表或其他操作。
template <typename... Arguments> returntype functionname(Arguments... args);
template <typename... Arguments> returntype functionname(Arguments&... args);
template <typename... Arguments> returntype functionname(Arguments&&... args);
template <typename... Arguments> returntype functionname(Arguments*... args);
template <typename... Arguments> returntype functionname(const Arguments&... args);

可变参数模板使用 sizeof...() 运算符

template<typename... Arguments>
void tfunc(const Arguments&... args)
{
    constexpr auto numargs{ sizeof...(Arguments) };

    X xobj[numargs]; // array of some previously defined type X

    helper_func(xobj, args...);
}

展开参数包(Parameter Pack Expansion):

  • 展开参数包的基础形式:args... 是一个参数包,你可以将其展开到各种上下文中,如函数调用、构造函数调用、表达式等。

    template<typename... Args>
    void function(Args... args) {
        // 这里需要展开 args... 参数包
    }
    
  • 递归展开:每次递归调用 print,会处理一个参数并将剩余的参数继续传递下去,直到参数包为空。这时,调用的是不带参数的基函数 print(),这就是递归的终止条件。

    void print() {
        std::cout << "End of recursion" << std::endl;
    }
    
    template<typename T, typename... Args>
    void print(T first, Args... rest) {
        std::cout << first << std::endl;
        print(rest...);  // 递归展开参数包
    }
    
    int main() {
        print(1, 2, 3, "Hello", 4.5);
        return 0;
    }
    
  • 使用初始化列表展开:C++11 中,也可以利用初始化列表 {} 进行参数包展开,常用于执行一些表达式的副作用,如输出或计算。这里 (std::cout << args << std::endl, 0)... 是参数包展开的关键部分,它将 args... 中的每个参数依次应用到 std::cout << args << std::endl 表达式中。

    template<typename... Args>
    void print(Args... args) {
        (void)std::initializer_list<int>{(std::cout << args << std::endl, 0)...};
    }
    
    int main() {
        print(1, 2, 3, "Hello", 4.5);
        return 0;
    }
    
  • C++17 Fold 表达式:C++17 引入了 fold 表达式,这是展开参数包的最简洁方法。fold 表达式(std::cout << ... << args) 会将参数包 args... 中的每个参数依次应用到 << 操作符中。最终结果是将所有参数依次输出。

    template<typename... Args>
    void print(Args... args) {
        (std::cout << ... << args) << std::endl;
    }
    
    int main() {
        print(1, 2, 3, "Hello", 4.5);
        return 0;
    }
    

类型萃取

基本类型判断萃取

  • std::is_integral<T>:判断类型 T 是否为整数类型(如 intchar 等)。

    std::cout << std::is_integral<int>::value << std::endl;  // 输出: 1 (true)
    std::cout << std::is_integral<float>::value << std::endl;  // 输出: 0 (false)
    
  • std::is_floating_point<T>:判断类型 T 是否为浮点数类型(如 floatdouble 等)。

    std::cout << std::is_floating_point<double>::value << std::endl;  // 输出: 1 (true)
    
  • std::is_pointer<T>:判断类型 T 是否为指针类型。

    std::cout << std::is_pointer<int*>::value << std::endl;  // 输出: 1 (true)
    std::cout << std::is_pointer<int>::value << std::endl;  // 输出: 0 (false)
    

类型修饰符萃取

  • std::add_const, std::remove_const:用于添加或移除类型的 const 限定符。
  • std::add_volatile, std::remove_volatile:用于添加或移除类型的 volatile 限定符。
  • std::remove_cv, std::add_cv:同时处理类型的 constvolatile 修饰符。它们提供了一种方便的方法,可以同时移除或添加这两个修饰符。
  • std::remove_reference<T>:移除类型 T 的引用限定符(包括左值和右值引用)。std::add_lvalue_reference<T>:将左值引用限定符添加到类型 Tstd::add_rvalue_reference<T>:将右值引用限定符添加到类型 T

条件选择萃取

根据条件选择不同的类。

  • std::conditional<Condition, T1, T2>:根据 Condition 选择 T1T2 作为类型。
  • std::enable_if<Condition, T>:当 Conditiontrue 时,类型为 T,否则此模板不参与重载。

类型转换萃取

用于在类型之间进行转换

  • std::make_signed<T>:将类型 T 转换为对应的有符号整数类型。
  • std::make_unsigned<T>:将类型 T 转换为对应的无符号整数类型。

类型判断萃取

判断两个类型之间的关系。

  • std::is_same<T1, T2>:判断类型 T1T2 是否相同。
  • std::is_base_of<Base, Derived>:判断 Base 是否为 Derived 的基类。

标签:std,...,args,参数,template,类型,模板
From: https://www.cnblogs.com/sfbslover/p/18402052

相关文章

  • g++如何判断>>是模板结束还是右移操作符
    intro在使用模板声明中,有一个经典的问题就是如何区分模板声明中的">>"是右移操作符还是一个模板声明的结束标志。好在新的C++标准削弱了这个很强的限制,而是允许reasonable的、根据上下文对符号进行不同的解析。C++11improvesthespecificationoftheparsersothatmultipl......
  • 设计模式之模板方法模式(三分钟学会一个设计模式)
    模板方法模式(TemplateMethodPattern)也称之为模板模式(TemplatePattern),是设计模式中最简单的模式之一。先来看定义:定义一个操作中算法的骨架(模板),将一些步骤延迟到子类中,模板方法使得子类可以不改变算法的结构即可重新定义算法某些特定的步骤。这个定义还是有一些晦涩,我的理解是......
  • 模板化-上线文件的流程步骤
    1.服务和分支,避免上线服务遗漏,及定义上线的优先级先后顺序。2.apollo配置,检查上线的pro环境的apollo配置,否则项目启动因为缺少配置会启动报错。3.SQLDMS,上线之前先执行脚本,否则会因为缺少字段而导致系统报错。flow系统加上客户和商户的会员号字段需求,上线之前忘记了。ALTERTA......
  • aspose word指定位置插入图片,借助word模板文件中的书签来定位 及Java 获取网络图片
    asposeword指定位置插入图片,借助word模板文件中的书签来定位 及Java 获取网络图片链接:asposeword模板文件生成pdfhttps://www.cnblogs.com/oktokeep/p/16615900.html在Aspose.Words中,您可以使用DocumentBuilder类在指定位置插入图片。以下是一个简单的示例代码,展示如何实现......
  • 【C++】模板初阶
    【C++】模板初阶1.函数模板(1).函数模板概念(2).函数模板格式(3).函数模板的原理(4).函数模板的实例化2.类模板(1).类模板的定义格式(2).类模板的实例化1.函数模板(1).函数模板概念函数模板代表了一个函数家族,该函数模板与类型无关,在使用时被参数化,根据......
  • 【生日视频制作】酒吧一群美女车展模特大屏幕视频改字AE模板修改文字软件生成器教程特
    生日视频制作教程酒吧一群美女车展模特大屏幕视频改字AE模板修改文字特效广软件告生成神器素材祝福玩法AE模板工程怎么如何做的【生日视频制作】酒吧一群美女车展模特大屏幕视频改字AE模板修改文字软件生成器教程特效素材【AE模板】生日视频制作步骤:安装AE软件下载......
  • 【生日视频制作】酒吧大屏幕视频改字AE模板修改文字软件生成器教程特效素材【AE模板】
    生日视频制作教程酒吧大屏幕视频改字AE模板修改文字特效广软件告生成神器素材祝福玩法AE模板工程怎么如何做的【生日视频制作】酒吧大屏幕视频改字AE模板修改文字软件生成器教程特效素材【AE模板】生日视频制作步骤:安装AE软件下载AE模板把AE模板导入AE软件修改图......
  • pbootcms模板忘记后台密码怎么找回?
    此工具用于忘记PbootCMS后台用户账号密码时进行重置。新建一个php文件,然后写入下面代码。稍后上传网站根目录, 访问文件就可以进入重置页面,后续根据提示操作即可。 <?php/***@copyright(C)2016-2099HnaoyunInc.*@authorXingMeng*@[email protected]*@d......
  • 【生日视频制作】长腿美女模特坐在椅子上打招呼大屏幕AE模板修改文字软件生成器教程特
    生日视频制作教程长腿美女模特坐在椅子上打招呼大屏幕文字AE模板修改文字特效广软件告生成神器素材祝福玩法AE模板工程怎么如何做的【生日视频制作】长腿美女模特坐在椅子上打招呼大屏幕AE模板修改文字软件生成器教程特效素材【AE模板】生日视频制作步骤:安装AE软件......
  • 推荐5款免费、开箱即用的Vue后台管理系统模板
    前言在现今的软件开发领域,Vue.js凭借其高效、灵活和易于上手的特性,成为了前端开发的热门选择。对于需要快速搭建企业级后台管理系统的开发者而言,使用现成的Vue后台管理系统模板无疑是一个明智之举。本文大姚将为你推荐5款开源、免费、开箱即用的Vue后台管理系统模板,帮助你快速启动......