C++开发基础——可变参数与可变参数模板

C++ 可变体(variant) 那么给他ItCat这个用户自定义类型加一个默认构造器,那么在可变体在初始化过程中,就能从类型参数列表<ItCat,int, float>中的第一个ItCat获得一个默认构造器。下面的代码是声明一个可变体的用法,在variant关键字的尖括号内,依次指定可变体的的数据类型。传递给,std::visit回调的函数,而这回调函数就是所谓的“访问者”,以实现一些非常复杂的业务逻辑。的C++编译器来说,无疑是给它增加困扰,而C++编译器对待这种模棱两可的值,它默认匹配值的数据类型是。的情况下,会得到一个编译器错误。 阅读详情
AI摘要

本文详细介绍了可变参数在C/C++中的应用,包括C语言中的可变参数函数、va_list宏,C++中的initializer_list和可变参数模板,以及C++11和C++17的新特性如sizeof...和编译期if条件判断。

一,可变参数

1.基础概念

可变参数在C语言和C++语言编程中都有应用。

可变参数的含义是:在函数传参的时候,参数的数量、类型都是可变的,不确定的。

在C语言中,应用到可变参数的是可变参数函数和可变参数的宏。

在C++语言中,C++11标准提供了两种使用可变参数的方式:

1.如果可变参数的参数类型相同,可以使用标准库中的initializer_list。

2.如果可变参数的参数类型不同,可以使用可变参数模板。

C语言中,在定义可变参数函数时,使用省略号"..."表示参数是可变的。

简单代码样例如下:

void printf(const char* format, …);

可变参数的使用可以让代码结构更精简。

2.可变参数相关的宏定义

在C语言中,一般需要借助相关的宏定义来实现可变参数,常见的宏定义如下:

va_arg:每一次调用va_arg会获取当前的参数,并自动更新指向下一个可变参数。

va_start:获得可变参数列表的第一个参数,开始使用可变参数列表。

va_end:结束对可变函数列表的遍历,释放va_list。

va_list:存储可变参数列表的具体信息。

    简单介绍就是,va_start用于开始使用可变参数,va_arg用于获得下一个可变参数,va_end用于释放va_list。

    它们都包含在头文件"<stdarg.h>"中

这些宏定义在具体应用时的语法如下:

type va_arg(
   va_list arg_ptr,
   type
);

void va_end(
   va_list arg_ptr
);

void va_start(
   va_list arg_ptr,
   prev_param
);

void va_start(
   arg_ptr
); // (deprecated Pre-ANSI C89 standardization version)

注意,如果自定义参数和可变参数同时在函数中出现,为了不导致编译出错,将可变参数放在形参列表的最后一个位置。

void func(char parm_1, int parm_2, ...);

完整代码样例:

#include <stdio.h>  
#include <stdarg.h>    
void vout(int max, ...)
{
    va_list arg_ptr;
    int args = 0;
    char* days[7];
    va_start(arg_ptr, max);
    while (args < max)
    {
        days[args] = va_arg(arg_ptr, char*);
        printf("Day:  %s  \n", days[args++]);
    }
    va_end(arg_ptr);
}
int main(void)
{
    vout(3, "Sat", "Sun", "Mon");
    printf("\n");
    vout(5, "Mon", "Tues", "Wed", "Thurs", "Fri");
}

运行结果:

Day:  Sat
Day:  Sun
Day:  Mon

Day:  Mon
Day:  Tues
Day:  Wed
Day:  Thurs
Day:  Fri

3.预定义标识符_VA_ARGS__

    对于可变参数相关的代码编写,除了使用省略号来表示可变参数列表,也可以使用__VA_ARGS__ 预定义标识符来表示可变参列表。

    该语法在C99标准中被引入,可以简单了解一下。

    可以用"__VA_ARGS__"表示"..."位置的所有参数,用法如下:

#define PRINT(...) printf(__VA_ARGS__)

完整代码样例:

#include <stdio.h>
#define DEBUG
#ifdef DEBUG
#define PRINT(...)  fprintf(stderr, __VA_ARGS__)
#else
#define PRINT(...)  printf(__VA_ARGS__)
#endif
int main(void)
{
    const char* s = "abc";
    int n = 123;
    PRINT("%d\n", n);
    PRINT("%s %d\n", s, n);
}

 运行结果:

123
abc 123

二,标准库模板initializer_list

initializer_list模板在函数声明中可以代表可变参数列表。

initializer_list中的参数可以使用迭代器来访问。

initializer_list实例中传入参数时需要使用{}把多个参数括起来。

代码样例:

initializer_list<int> i1{ 1, 2, 3, 4 };

Demo1:  初始化类成员

#include <iostream>
#include <vector>
#include <initializer_list>
class Point {
    std::vector<int> arr;
public:
    //Constructor accepts a initializer_list as argument
    Point(const std::initializer_list<int>& list) : arr(list)
    {}
    void display() {
        for (int i : arr)
            std::cout << i << " , ";
        std::cout << std::endl;
    }
};
int main() {
    Point pointobj({ 1, 2, 3, 4, 5 });
    pointobj.display();
    return 0;
}

运行结果:

1 , 2 , 3 , 4 , 5 ,

Demo2:结合lambda表达式一起使用

#include <iostream>
#include <initializer_list>
using namespace std;
template<typename... Args>
void print(Args... args)
{
    std::initializer_list<int>{
        ([&] { cout << args << " "; }(), 0)...
    };
}
int main()
{
    print(1, 2, "3A", 4);
    return 0;
}

运行结果:

1 2 3A 4

三,可变参数模板

1.基础概念

可变参数模板是支持任意数量和类型的参数的类模板或函数模板。

在可变参数模板中,可变数目和类型的参数列表被称为参数包(parameter pack)。

可变参数模板的参数包,分为模板参数包(template parameter pack)和函数参数包(function parameter pack)。

在模板参数位置的可变参数被称为模板参数包,在函数参数位置的可变参数被称为函数参数包。

可以使用sizeof...运算符获取参数包中具体的参数数量。

样例如下: 

//Args是一个模板参数包;args是一个函数参数包
template <typename... Args>
void func(Args... args);

如上所示,在一个模板参数列表中:

class...或typename...表示接下来的参数是零个或多个类型列表。

类型名...表示接下来的参数是零个或多个给定类型的函数参数列表。

比较一下"typename T"和"typename.. Args":

Args和T的差别是,T与一种类型匹配,而Args与任意数量(包括零)的类型匹配。

完整代码样例:

Demo1:

#include <iostream>
template <typename T>
void printAllImpl(T item) {
       std::cout << item << ' ';
}
template <typename T, typename ...Args>
void printAllImpl(T item, Args ... args) {
       printAllImpl(item);
       printAllImpl(args...);
}
template <typename... Args>
void printAll(Args&&... args) {
       printAllImpl(std::forward<Args>(args) ...);
       std::cout << '\n';
}
int main() {
       printAll(3, 2, 1);
       printAll(8.2, 2, 1.1, "A");
       printAll(23, 32, 8, 11, 9);
}

运行结果: 

3 2 1
8.2 2 1.1 A
23 32 8 11 9

2.参数包的递归解析

可变参数列表中,参数包的展开方式为递归展开,即将函数参数包展开,对列表中的第一项进行处理,再将余下的内容传递给相同函数递归调用,以此类推,直到参数列表为空。

代码样例:

#include <iostream>
template<typename T, typename... Args>
void show_list(T value, Args... args)
{
       std::cout << value << ", ";
       show_list(args...); //递归调用
}
int main()
{
       int n = 2;
       double m = 3.0;
       std::string str = "test";
       show_list(1, n, m);
       show_list(1, n, m * m, str);
       return 0;
}

以上代码在VS2019中运行时,会报以下编译错误:

“show_list”: 未找到匹配的重载函数
“void show_list(T,Args...)”: 应输入2个参数,却提供了0个

    出现以上问题的原因是,可变参数函数模板通常是递归的。函数在第一次调用时,会使用参数包中的第一个实参,然后递归调用自身来陆续使用参数包中的剩余实参。为了终止递归,我们还需要定义一个非可变参数的函数模板或者普通函数。

    以下代码都包含终止递归的函数模板。

    Demo1: 

#include <iostream>

//用来终止递归并处理参数包中最后一个元素
template<typename T>
void show_list(T value)
{
    std::cout << value << ", ";
}

//参数包中除了最后一个元素之外的其他元素都会调用这个版本的show_list
template<typename T, typename... Args>
void show_list(T value, Args... args)  
{
    std::cout << value << ", ";
    show_list(args...); //递归调用
}

int main()
{
    int n = 2;
    double m = 3.0;
    std::string str = "test";
    show_list(1, n, m);
    show_list(1, n, m * m, str);
    return 0;
}

运行结果:

1, 2, 3, 1, 2, 9, test,

Demo2:

#include <iostream>
void tprintf(const char* format) //终止递归调用
{
    std::cout << format;
}
template<typename T, typename... Targs>
void tprintf(const char* format, T value, Targs... Fargs)
{
    for (; *format != '\0'; format++)
    {
        if (*format == '%')
        {
            std::cout << value;
            tprintf(format + 1, Fargs...); //递归调用
            return;
        }
        std::cout << *format;
    }
}
int main()
{
    tprintf("% world% %\n", "Hello", '!', 123);
}

运行结果:

Hello world! 123

特殊情况,当不涉及"typename T"的使用时,可以不需要单独定义一个非可变参数的函数模板来终止递归。

Demo3:

#include <iostream>
using namespace std;
template<typename... Argv>
void print_func(Argv... argv)
{
    cout << "print_func() is called with "
         << sizeof...(Argv)
         << " argument(s)." << endl;
}
int main(void)
{
    print_func();
    print_func(4, "a");
    print_func("a", "b", "c");
    return 0;
}

运行结果:

print_func() is called with 0 argument(s).
print_func() is called with 2 argument(s).
print_func() is called with 3 argument(s).

3.参数包展开过程拆解

演示代码:

#include <iostream>
using namespace std;
void print()
{
       cout << "I am empty.\n";
}
template <typename T, typename... Types>
void print(T var1, Types... var2)
{
       cout << var1 << endl;
       print(var2...);
}
int main()
{
       print(1, 2, 3.14, "test");
       return 0;
}

过程拆解: 

main函数中,第一次调用print,传递的实参:1,参数包剩余元素:2, 3.14, "test"。

第一次递归调用print,传递的实参:2,参数包剩余元素:3.14, "test"

第二次递归调用print,传递的实参:3.14,参数包剩余元素:"test"

第三次递归调用print,传递的实参:"test",参数包中的元素已全部用完。

由于参数包中的元素为空,退出递归,最后调用的是具体函数print()。

运行结果:

1
2
3.14
test
I am empty.

4.sizeof...运算符

    由于带有"typename T"参数的可变参数的模板函数,总是需要再定义一个同名的模板函数或者普通函数来搭配使用,使得代码特别重复。

    为了解决以上问题,可以使用"sizeof..."运算符来保证,在不重复定义同名函数的情况下让递归退出。

    "sizeof..."运算符可以判断参数包中的元素数量。

    退出递归的方式: 判断当参数包的元素个数为零时,退出函数调用。

sizeof...用法演示:

#include <cassert>
#include <stdio.h>
template<class...A>
int func(A...arg) {
    return sizeof...(arg);
}
int main(void) {
    if (func<int>(1, 2, 3, 4, 5) == 5) {
        printf("the num of arg is 5");
    }
    return 0;
}

运行结果: 

the num of arg is 5

sizeof...在结束递归中的使用

Demo1:

#include <iostream>
template<typename T, typename... Args>
void print_2(T value1, Args... args) {
    std::cout << value1 << ", ";
    if(sizeof...(args) > 0) {
        print_2(args...);
    }
}
int main()
{
    print_2(1, 2, "A");
}

以上用法无法导致递归终止,而且还会引起编译报错,原因是if判断无法在该函数模板中生效。为了解决以上问题,C++17标准中引入了编译期if条件判断的表达式"if constexpr"。

Demo2:

#include <iostream>
template<typename T, typename... Args>
void print_2(T value1, Args... args) {
    std::cout << value1 << ", ";
    if constexpr (sizeof...(args) > 0) {
        print_2(args...);
    }
}
int main()
{
    print_2(1, 2, "A");
}

运行结果: 

1, 2, A,

四,参考阅读

《C++17入门经典》

《C++ primer》

《深入理解C++11》

https://www.sandordargo.com/blog/2023/05/03/variadic-functions-vs-variadic-templates

https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/va-arg-va-copy-va-end-va-start?view=msvc-170

https://www.ibm.com/docs/en/zos/2.3.0?topic=lf-va-arg-va-copy-va-end-va-start-access-function-arguments

https://www.sandordargo.com/blog/2023/05/03/variadic-functions-vs-variadic-templates

https://en.cppreference.com/w/cpp/language/parameter_pack

C/C++可变参数函数 一、C可变参数函数一般我们编程的时候,函数中形式参数的数目通常是确定的,在调用时要依次给出与形式参数对应的实际参数。但在某些情况下我们希望函数的参数个数可以根据需要确定,因此c语言引入可变参数函数。典型的可变参数函数的例子有printf()、scanf()等.先看代码:printf(“hello,world!”);其参数个数为1个。 printf(“a=%d,b=%s,c=%c”,a,b,c);其参 阅读详情

相关推荐

C++可变参数函数

C++可变参数函数

陈嘉怡的专栏 966

c++ 可变参数的三种实现方式

一个可变参数模板(variadic template)就是一个接受可变数目参数的模板函数或模板类。存在两种参数包:模板参数包(template parameter packet),表示零个或多个模板参数;说到这里,ubuntu(linux) 默认栈大小8M(使用命令 ulimit -a查看), Win下,Visual Studio 默认栈大小1M(连接器->系统)。函数参数为参数包的形式,使用递归展开。从本质上讲,逗号的作用是将一系列运算按顺序执行。整个逗号表达式的值为系列中最后一个表达式的值。

性感的小君君 9396

C++ 可变参数模板:实现通用的参数数量和类型的灵活模板

总结起来,可变参数模板是 C++ 中一个重要的特性,它允许我们编写通用的函数或类模板,可以接受任意数量和类型的参数。可变参数模板是 C++ 中一个强大的特性,它允许我们编写通用的函数或类模板,可以接受任意数量和类型的参数。通过使用可变参数模板,我们可以编写灵活的代码,适用于不同的使用场景。我们使用了递归调用的方式,每次递归处理一个参数,直到参数列表为空,调用终止递归的版本。下面,我将给出一个示例代码,演示如何使用可变参数模板来实现一个通用的打印函数,可以打印出任意数量和类型的参数。

Orion_O的博客 247

C++可变参数

参数列表的… … 表示函数的参数个数可变,典型的如printf() int printf (const char * szFormat, ...); 第一个参数是一个格式化字符串,后面是与格式化字符串中的代码相对应的不同类型的多个参数。 char* name = "fgq"; int age = 18; printf("info {name:%s, age:%d}\n",name, age) ; 使用…实现变参数函数的两种场景 1. 格式化字符串 使用场景: 类似于实现一个printf,输入一串格

weixin_39488566的博客 6615

计算机国际会议中的proceedings、conference、paper、workshop、demo:如何区分与选择?

本文详细解析了计算机国际会议中的核心概念:Conference(会议)是学术交流的主舞台,Paper(论文)是研究成果的书面呈现,被接收后收录于Proceedings(会议论文集)。Workshop(研讨会)聚焦前沿细分领域,Demo(演示)则侧重系统与工具的可交互展示。文章为研究者根据自身阶段与工作类型,如何区分与选择投稿目标提供了实用指南。

weixin_29269441的博客 562

Zemax非序列模式新手入门:从零搭建一个抛物面反射镜系统(含灯丝光源与探测器设置)

本文详细介绍了如何在Zemax非序列模式下从零搭建抛物面反射镜系统,包括灯丝光源配置、反射镜建模和探测器设置等关键步骤。通过实战指南,帮助光学设计新手快速掌握非序列模式的应用技巧,特别适合处理复杂光线传播场景如反射镜系统和杂散光分析。

weixin_28717431的博客 436

C++的...符号(可变参数实现)

可变参数模板是 C++ 中实现可变参数最强大和安全的方式,虽然语法看起来复杂,但提供了完全的编译时类型检查。这是理解可变参数模板的关键点。:类型不安全,需要手动管理参数,容易出错。,可以接受任意数量的类型参数。这是最现代、最安全的方式。紧跟在参数包名字后面。

ULTRAmanTAROACE的博客 393

手把手教你用示波器实测LVDS/CML信号:从波形解读到故障排查(附实测图)

本文详细介绍了如何使用示波器实测LVDS和CML信号,从波形解读到故障排查的全过程。涵盖差分探头选择、示波器配置、标准波形特征解读、眼图分析技巧以及高速信号捕获要点,帮助硬件工程师快速诊断和解决信号完整性问题。附实测图和案例,提升高速数字电路设计效率。

weixin_27215337的博客 199

可变参数模板

可变参数模版是C++11新增的最强大的特性之一,它对参数进行了泛化,能支持任意个数、任意数据类型的参数。

Theonlyikun的博客 209

飞牛fnNAS虚拟机标准安装

飞牛NAS是一款基于Debian开发的国产免费NAS系统,支持x86架构设备,可将闲置硬件改造为NAS服务器。系统安装简便,支持多种存储模式与硬盘休眠功能,具备智能影视管理、照片备份等实用功能,并提供多种远程访问方式。飞牛NAS还支持Docker扩展,目前已承诺永久免费。文章详细介绍了在VMware虚拟机中安装飞牛NAS的步骤,包括下载镜像、创建虚拟机、初始化设置等过程,并展示了创建共享文件夹等基本操作,帮助用户快速上手这款功能强大的免费NAS系统。

dgnankai的专栏 3257

Python 爬虫实战:赛事分析平台构建与比赛数据抓取

在体育赛事日益丰富的今天,对比赛数据的收集与分析对于运动员、教练团队以及体育爱好者都具有重要意义。通过构建一个赛事分析平台,我们可以系统地抓取、整理和展示各类比赛数据,为用户提供全面的赛事洞察。本文将深入讲解如何利用 Python 爬虫技术实现这一平台的构建,涵盖从目标网站分析到数据可视化展示的全过程。

u014481728的博客 3180

C++可变参数函数全解析:省略号、变参模板与折叠表达式

C++可变参数函数全解析:省略号、变参模板与折叠表达式。

Haku_yyf的博客 656

Halcon 深度学习实战:PCB 缺陷检测模型的 TensorRT/OpenVino 加速推理

本文介绍了如何利用TensorRT和OpenVino对Halcon深度学习模型进行加速优化,以提升PCB缺陷检测系统的实时性能。文章详细阐述了模型加速框架的选择策略(根据硬件选用TensorRT或OpenVino)、优化流程实施(包括混合精度优化和模型导出)以及加速后的推理实现。实验结果表明,优化后的模型体积缩小40%,推理速度提升2-5倍(GPU环境下从79ms降至38ms,CPU环境下从3804ms降至2152ms),同时保持检测精度。通过完整的代码示例展示了从模型加速到实际部署的全流程,为工业视觉场景

LIN943168247的博客 535

C11-可变参数模板-Variadic Templates可变参数模板

/************************************************************************************** ************************* 1.Variadic Templates可变参数模板 ************************* *******************************************************************************.

MorningStar的博客 1007

181、LLC谐振变换器的PCB设计实战(文件归档)

PCB设计实战经验总结:LLC谐振变换器的关键要点 本文通过实际案例总结了LLC谐振变换器PCB设计中的核心经验和常见误区。重点包括: 文件命名规范(项目代号_板卡类型_版本号_日期格式) 四层板标准层叠结构设计要点 谐振回路走线原则(宽度、长度控制) 地线处理技巧(功率地/控制地隔离) 散热设计注意事项(MOSFET过孔阵列、变压器布局) 完整的文件归档清单(Gerber、钻孔、装配图等) 作者特别强调,良好的设计归档习惯能显著降低生产问题概率,建议采用双重备份机制。文中多个真实案例(如谐振频率偏移、EM

Jack010169的博客 43

华为OD面试八股真题 - 操作系统 - 1

华为OD技术面,操作系统相关八股真题提供详细解答,这篇博客主要涉及于进程和线程相关知识点

qq_45776114的博客 1639

探索C++模板的奥秘:《C++ Templates 第二版》全面解析

在C++编程的世界中,模板是一种强大而复杂的工具,它们为开发者提供了编写高效、灵活且可维护代码的能力。《C++ Templates 第二版》由三位C++领域的专家David Vandevoorde、Nicolai M. Josuttis和Douglas Gregor共同撰写,为读者深入解析了C++模板的各个方面,是每一位C++开发者的必备读物。 ## 项目介绍 《C++ Templates 第...

gitblog_00760的博客 1229

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

c++总结-05-模板与泛型编程

模板与泛型编程

FairLikeSnow的博客 1420

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

可变参数模板(C++11)

定义 可变参数模板可以创建参数数量可变的模板函数和模板类。 模板参数包、函数参数包 参数包的定义 C++11中,可使用一个用省略号表示的元运算符来声明模板参数包。 template<tpyename...Args> //Args是模板参数包 void show_list(Args...args> //args是函数参数包 展开参数包 将省略号放在参数参数包名的右...

Jibeon的学习之路 238

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

C++ 模板编程详解:从基础到元编程

模板是 C++ 的灵魂,掌握它意味着掌握了类型泛化、编译期逻辑和高性能库设计的能力。从基础的函数模板、类模板,到特化、偏特化,再到复杂的元编程与类型萃取,模板为 C++ 提供了独特的表达力。掌握模板,需要不断实践与抽象能力的提升。建议配合阅读 STL 源码、Boost MPL、C++20 Concepts 等进一步探索其边界。

m0_74823364的博客 889

C++11万能引用与完美转发以及可变参数模板

本文介绍了C++11中的四个重要特性:1. 万能引用(T&&)可以自动识别参数类型;2. 完美转发(forward)能精确保持参数原有值类别;3. 移动构造函数和移动赋值运算符的实现规则及注意事项;4. 可变参数模板的使用方法和参数包展开技巧。文章通过代码示例详细演示了这些特性的实际应用,并比较了push_back和emplace_back的性能差异。这些新特性显著提升了C++的编程效率和性能表现。

2302_79772464的博客 746

C++模板进阶:技巧与实战

C++模板的进阶用法包括模板特化、可变参数模板、模板元编程等。这些进阶技术组合使用可以构建出高度灵活且类型安全的泛型代码,是现代C++开发的核心工具。C++20引入概念(concepts)对模板参数进行约束,使错误信息更友好。可变参数模板允许接受任意数量的模板参数,使用递归展开或折叠表达式处理。模板特化允许为特定类型提供定制化的实现。利用模板在编译期进行计算,典型应用包括类型运算和常量计算。允许模板参数本身是模板,用于创建更灵活的容器适配器等。使用using创建模板别名,简化复杂类型声明。

m2QAcEDuMc的博客 285

C++模板编程:从函数模板到可变参数,掌握泛型编程核心

泛型编程是现代编程语言中实现代码复用的核心技术,其核心思想是将算法与数据类型解耦,通过参数化类型来编写通用代码。C++模板作为泛型编程的实现机制,在编译期进行类型检查和代码生成,实现了类型安全与零运行时开销的统一。这一技术不仅支撑了C++标准模板库(STL)的设计,也是构建高性能、可复用组件的基础。在实际工程中,模板技术广泛应用于容器、算法、智能指针等场景,通过函数模板实现算法泛化,类模板构建通用数据结构,可变参数模板处理任意数量参数,完美转发保持参数值类别。掌握模板编程能有效提升代码的抽象层次和复用性,是

weixin_34174322的博客 408

【C++:C++11】深入浅出 C++11:右值引用、移动语义、可变参数模板与完美转发详解

🔥艾莉丝努力练剑:个人主页❄专栏传送门:《C语言》、《数据结构与算法》、C/C++干货分享&学习过程记录、Linux操作系统编程详解、笔试/面试常见算法:从基础到进阶、测试开发要点全知道⭐️为天地立心,为生民立命,为往圣继绝学,为万世开太平🎬艾莉丝的简介:🎬艾莉丝的C++专栏简介:目录C++学习阶段的三个参考文档3 ~> 右值引用 && 移动语义3.6 类型分类3.7 引用折叠3.7.1 语法和原理3.7.2 最佳实践3.8 完美转发:保持原来属性往下传3.8.1 语法和原理3.8

艾莉丝努力练剑的博客,感谢大家一直以来的对艾莉丝的支持和鼓励,uu们如果对C/C++方向感兴趣的话,可以通过艾莉丝主页的微信名片加艾莉丝的好友,和努力练剑的艾莉丝一起加油! 1192

C++模板与泛型编程详解

摘要: 模板是C++实现泛型编程的核心机制,通过编写与类型无关的通用代码提升复用性。类比饼干模具,模板定义结构,具体类型由用户决定。主要分为函数模板(如通用max())和类模板(如容器MyVector),支持类型安全且避免重复代码。现代C++特性(如自动推导、概念约束)进一步优化了模板的可读性和安全性。使用时应遵循YAGNI和KISS原则,优先解决实际需求,避免过度复杂化。典型应用包括通用算法(排序、转换)和策略模式实现,但需注意编译时代价和代码膨胀问题。模板在STL中广泛应用,是高效、灵活编程的重要工具。

leohu0723的博客 1000

C++模板编程:从函数模板到类模板,掌握泛型编程核心

泛型编程是C++中实现代码复用和类型安全的核心技术,它允许开发者编写独立于数据类型的通用算法和数据结构。其原理是通过模板机制,在编译期根据具体类型生成特化代码,从而实现零运行时开销的抽象。这种技术价值在于显著提升代码的复用性、可维护性和性能,是构建如STL标准库等大型软件基础设施的基石。在实际应用场景中,泛型编程广泛用于容器类、算法库、元编程和设计模式实现。本文聚焦于C++模板编程,深入解析函数模板与类模板的实战应用,并探讨模板特化、可变参数模板等进阶技巧,帮助开发者规避代码膨胀等常见陷阱,提升工程实践能力

weixin_34161083的博客 523
上一篇: C++开发基础——类对象与构造析构
下一篇: C++开发基础——函数模板
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

打赏作者

程序员与背包客_CoderZ

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

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

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

打赏作者

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

抵扣说明:

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

余额充值