C++开发基础——函数模板

Cpp-泛型编程基础 Cpp-泛型编程基础 哇,很久没有写cpp了,写得太挫了,主要是。emm,好像数据结构作业是实现线程池,趁此机会好好学一遍cpp吧,不要再吹水了。只希望。 C++是一门很强大的语言,泛型编程一般来说可望而不可及,今天来啃一下这小基础吧。 函数重载 假设要比较两个数的值,我们可以使用两个函数进行重载: int compare(const int&a, const int&b) { if 阅读详情

一,函数模板

1.基础概念

模板编程是C++中泛型编程的基础。

一个模板可以是创建类或者函数的蓝图。

模板编程分两种,分别是算法抽象的模板、数据抽象的模板。算法抽象的模板以函数模板为主,数据抽象的模板以类模板为主。

基于函数模板生成的函数定义被称为模板的一个实例。

模板的定义以关键字template开始,后跟一个由尖括号"<>"括起来的模板参数列表。

2.函数模板的简单样例

函数模板的开头:template

定义模板参数的关键字:typename

模板参数样例:T1, T2

函数参数样例:a, b

template <typename T1, typename T2>
void func(T1 a, T2 b)
{
    //process code
}

补充:在C++98标准添加关键字typename之前,C++也可以使用关键字class来为函数模板创建模板参数列表。

代码样例:

template <class T>
void Swap(T &a, T &b)
{
    T temp;
    temp = a;
    a = b;
    b = temp;
}

3.函数模板的实例化

函数模板的实例化是指,编译器根据函数模板和具体的数据类型生成函数定义。

函数模板在实例化以后,模板参数会变成具体的数据类型,比如int, char等。

对于某一种具体的数据类型,比如int,无论以这个数据类型调用多少次函数模板,最后只生成一次该类型的模板实例。

所以,对于相同的数据类型,第一次调用函数模板的时候才会生成实例,后面再次调用的时候,都是直接使用该实例。

当编译器遇到一个函数模板的定义时,并不会马上生成相关代码,只有当我们将函数模板实例化成一个函数定义时,编译器才会生成代码。

代码样例:

a.函数模板

template <typename T>
T add(T num1, T num2) {
   return (num1 + num2);
}

b.函数模板的实例化

int result1 = add<int>(2, 3);
double result2 = add<double>(2.2, 3.3);

实例化过程的图示:

 在项目工程中,我们通常将类的定义放在头文件中,将类的成员函数的定义放在源文件中,将普通函数的声明放在头文件中,将普通函数的定义放在源文件中,但是函数模板的规则和它们不一样。

    为了让编译器为实例化后的函数模板生成代码,编译器需要同时知道函数模板的声明和定义,因此函数模板的定义也需要放在头文件中。

4.函数模板的引用传参

 对于以下函数模板:

template <typename T>
T larger(T a, T b)
{
    return a > b ? a : b;
}

该函数模板实例化以后生成的函数,需要按值传递的方式接收实参。

由于按值传送对象,会导致不必要地复制这些对象,因此,推荐使用const引用的方式定义模板参数。

template <typename T>
const T& larger(const T& a, const T& b)
{
    return a > b ? a : b;
}

5.函数模板的返回类型推断

对于无返回值的函数模板,可以把返回值类型写为void,比如最开始提到的:

template <typename T1, typename T2>
void func(T1 a, T2 b)

有的函数模板,返回值类型和参数一致,同为T,比如:

template <typename T>
T larger(T a, T b)

但是,当返回值类型和参数不一致时,得想办法让编译器可以推断返回值类型。

最简单的方式是使用auto关键字。

template <typename T1, typename T2>
auto larger(const T1& a, const T2& b)
{
    return a > b ? a : b;
}

但是,使用auto来推导函数的返回值类型时,会默认去掉引用和const限定符,因此,以上方式会导致返回值发生不必要的复制。

        因此,为了让返回值被const修饰,且采取引用的方式来传值,需要显式地加上"const &",以上代码可以改为: 

template <typename T1, typename T2>
const auto& larger(const T1& a, const T2& b)
{
    return a > b ? a : b;
}

还有一种更好的方式,C++11标准引入了decltype关键字,decltype相当于"const auto&",因为decltype在做类型推导时,不会去掉引用和const限定符。

但是decltype的用法不能像auto一样,直接放在函数名前面。

decltype用法分两种:

方式1.拖尾方式:decltype(返回值相关代码)

template <typename T1, typename T2>
auto larger(T1 a, T2 b) -> decltype(a > b ? a : b)
{
    return a > b ? a : b;
}

方式2.和auto关键字结合:decltype(auto)

template <typename T1, typename T2>
decltype(auto) larger(T1 a, T2 b)
{
    return a > b ? a : b;
}

第一种用法需要把返回值相关的代码逻辑重复写一遍,第二种用法更简洁。

6.模板参数可以指定默认值

可以用具体的数据类型为模板参数指定默认值。

例如:当函数经常使用int类型的参数时,指定模板参数的默认值为int。

template <typename T1=int, typename T2>
void func(T1 a, T2 b)

7.非类型的模板参数

模板参数分两种:

1.类型模板参数

2.非类型模板参数

由尖括号"<>"括起来的模板参数列表中,除了可以包含类型模板参数,还可以包含非类型模板参数。

以上提到的"typename T1, typename T2"中的"T1, T2"都属于类型模板参数,而"int n,  float m"中的"n, m"都属于类型模板参数非类型模板参数。

类型模板参数经过实例化会变成具体类型。

非类型模板参数经过实例化会变成具体的值。

代码样例: 

应用场景:比较不同长度的字符串字面常量。

函数模板定义了两个非类型模板参数,参数N表示第一个数组的长度,参数M表示第二个数组的长度。

数组采用const和引用的方式传参。

template<int N, int M>
int compare(const char (&p1)[N], const char (&p2)[M])
{
    return strcmp(p1, p2);
}

非类型模板参数可以使用的数据类型: 

整型,如int、long等
枚举类型
对象类型的引用或指针
函数的引用或指针
类成员的指针

当模板参数列表中,同时有类型模板参数和非类型模板参数时,建议将非类型模板参数写在类型模板参数的前面。

代码样例:

template <int lower, int upper, typename T>
bool is_in_range(const T& value)
{
    return (value <= upper) && (value >= lower);
}

完整代码样例:

求任意数据类型,任意大小的数组的平均值。

#include <iostream>
template <typename T, int N>
T average(const T(&array)[N])
{
       T sum{};
       int i;
       for (i = 0; i < N; ++i)
       {
              sum += array[i];
       }
       return sum / N;
}
int main()
{
       double array_1[2]{ 1.1, 2.1 };
       std::cout << average(array_1) << std::endl;
       float array_2[]{ 1.0, 2.0, 3.0, 4.0 };
       std::cout << average(array_2) << std::endl;
       int array_3[] = { 1, 2, 3, 4 };
       std::cout << average(array_3) << std::endl;
       return 0;
}

运行结果:

1.6
2.5
2

8.inline/constexpr修饰的函数模板

和具体函数一样,函数模板可以用inline或constexpr修饰。

inline或constexpr在修饰时放在模板参数列表之后,返回值类型之前。

代码样例:

template <typename T>
inline T min(const T&, const T&);

9.函数模板的重载

函数模板的重载有两种方式:

方式1.用同名函数重载函数模板

方式2.用另一个函数模板重载已有模板

重载的代码样例:

template <typename T>
T larger(const T data[], size_t count)
{
    T result {data[0]};
    for (size_t i {1}; i < count; ++i)
    {
        if (data[i] > result)
            result = data[i];
    }
    return result;
}

template <typename T>
T larger(const std::vector<T>& data)
{
    T result {data[0]};
    for (auto& value : data)
    {
        if (value > result)
            result = value;
    }
    return result;
}

二,函数模板的特例 

1.基础概念

函数模板的特例是由原始的函数模板具体化而来的,因此,函数模板的特例也被称为函数模板的具体化(explicit specialization)。

函数模板的特例的定义必须放在函数模板的声明和定义之后。

当编译器找到与函数调用匹配的具体化定义时,将直接使用该函数模板的特例,而不再实例化函数模板。

函数模板的特例也以关键字template开头,但要省略参数,所以template后面的尖括号是空的。

函数模板的特例的定义需要传递具体的参数类型。

当函数模板的某个实例,需要被定义一种不同于原始函数模板的行为,就可以使用函数模板的特例去定义。

空的尖括号“<>”表示编译器不需要做类型推导。

函数模板特例的简单样例:

template <>
void func(int a, double b)
{
    //process code
}

2.代码样例

给定函数模板 larger(T1 a, T2 b)

template <typename T1, typename T2>
decltype(auto) larger(T1 a, T2 b)
{
    return a > b ? a : b;
}

由于该函数模板不适用于指针数据类型,因此,定义以下函数模板的特例。

函数模板的特例,在代码逻辑中相比原始的函数模板多了解引用操作。

template <>
int* larger<int*>(int* a, int* b)
{
    return *a > *b ? a : b;
    //解引用操作是为了让两个指针比较指向的数值而不是地址
}

普通函数,函数模板,函数模板特例的代码形式

//function
void Swap(int& a, int& b);

//template prototype
template <typename T>
void Swap(T& a, T& b);

//template explicit specialization
template <>
void Swap<int>(int& a, int& b);

3.编译时的匹配优先级

当某个具体的数据类型可以同时匹配上普通函数,函数模板,函数模板的特例时,普通函数的调用优先于函数模板特例,函数模板特例的调用优先于原始函数模板。

三,参考阅读

《C++17入门经典》

《C++ primer》

《深入理解C++11》

https://www.programiz.com/cpp-programming/function-template

点云配准SIFT+SI+RANSAC+ICP Spin Image(SI)是一种用于点云数据描述的特征描述子,广泛应用于三维点云配准、识别和重建等领域。它能够捕捉点云中的局部几何信息,具有旋转不变性和部分平移不变性等优点,是一种非常强大的特征描述子。Spin Image是一种强大的点云特征描述子,具有旋转不变性、局部几何信息捕捉等优点,适用于点云配准、目标识别和三维重建等多个领域。通过合理选择局部区域、建立参考框架和计算描述子,可以充分利用Spin Image描述点云的特征,从而实现各种三维场景分析和处理任务。 阅读详情

相关推荐

ComfyUI工作流换脸节点报错ReActorFaceSwap

找到自己ComfyUI安装目录的custom_nodes下是否有这个comfyui-reactor-node-main。大家在借鉴别人工作流进行AI换脸的时候,如果遇到ReActorFaceSwap报错提示,莫慌,看我的,两步解决问题。这里千万注意不要嵌套文件夹,保证点击去这个文件就可以看到内置的配置文件!找到自己ComfyUI安装目录的facerestore_models。如果有这个文件,直接跳过,去下一步。如果没有,可以去Git官网下载。

qq_70810809的博客 9015

Cpp-Templates-2ed完全指南:从C++11到C++20的终极模板编程教程

C++模板是C++11至C++20标准中最复杂也最强大的特性之一,是构建高性能基础设施库不可或缺的技术。本教程将带你从基础到进阶,全面掌握现代C++模板编程的核心技术与最佳实践。 ## 为什么模板是C++开发者的必备技能 🚀 模板作为C++的元编程基础,允许开发者编写与类型无关的通用代码,在保持类型安全的同时实现代码复用。无论是STL标准库、Boost库,还是现代C++基础设施,模板技术都扮

gitblog_00195的博客 683

C#上位机与VisionPro通用框架:视觉标定、通信联动与现场排坑实战

工业自动化设备的上位机开发,往往面临流程控制、视觉检测、通信交互等环节的重复搭建。C#作为主流工业语言,配合VisionPro视觉软件,可通过通用框架设计将状态机调度、相机采集、标定算法与串口/扫码枪通信等底层能力模块化,从而大幅降低项目交付成本。其核心原理在于:将设备工艺差异封装至配置层,视觉流程通过CogToolBlock工具链与VPP模板复用,九点标定建立像素与机械坐标系的映射关系。该方案已在螺丝锁付、点胶定位等多类产线落地,尤其适用于批量交付、换型频繁的视觉设备场景。这套从实践中沉淀的框架思路,以及

weixin_31102231的博客 338

《 C++ 点滴漫谈: 三十四 》从重复到泛型,C++ 函数模板的封神之路

C++ 函数模板是泛型编程的基石,它让我们可以编写类型无关、可复用的高效代码。本文从基础语法出发,深入讲解了类型推导、重载机制、特化策略与编译原理,并结合现代 C++(如 auto、lambda、concepts)展示了模板在实际项目中的高级用法。通过实战案例与调试建议,帮助读者全面掌握函数模板的理论与实践,迈入泛型编程的核心领域。

Lenyiin 2977

FPGA_AD9361实战

1.参考网站。

Pual_Georg的博客 748

eMMC数据擦除的方式

接下来主要是讲解erase、trim、discard的差异,涉及的command有CMD35、CMD36、CMD38。一般用来擦除整卡或者某些分区,如果只想擦除一个。以下是device status的部分解释。eMMC的数据擦除方式有6种,分别是。将会跳过写保护,只执行其他的范围。Discard的命令序列是。Erase的命令序列是。的范围有包含写保护,Trim的命令序列是。

DPJimmy的博客 1772

C++函数模板详解

经常有碰到函数模块的应用,很多书上也只是略有小讲一下,今天又狂碰到函数模块,无奈特地找来C++编程经典>翻阅一遍,终于有所全面了解..... C++函数模块基础知识: 一.  问题: 强类型语言要求我们为所有希望比较的类型都实现一个实例 int min( int a, int b ) { return a } double min( double a, double b ) {

记录一下学习笔记和看到值得记录的文章 746

使用spacy规则化提取自然语言文本信息

1. 安装spacy pip install spicy spicy还需要载入文本库,使用pip的下载方式: python3 -m spacy download en_core_web_sm 但是很有可能因为网络问题下载速度非常缓慢,所以可以选择到github上去直接下载(注意和自己的spacy版本匹配):github下载链接 下载*.tar.gz文件即可。 然后切换到下载路径, pip install en_core_web_sm-3.1.0.tar.gz 2. spacy的一些基础用法 使用spa

六六六六神的博客 1818

C++ 中函数模板和类模板有什么区别?

摘要: C++中的函数模板和类模板均支持参数化编程,但存在显著差异。函数模板通过隐式实例化(编译器自动推导类型)实现通用算法,适用于逻辑相同但数据类型不同的场景(如排序)。类模板需显式指定类型参数,用于构建通用数据结构(如栈、队列),其成员函数在实例化时全部生成。 特化方面,函数模板仅支持全特化(针对特定类型优化算法),而类模板支持全特化和部分特化(调整数据结构或行为)。函数模板特化语法简单,仅影响局部逻辑;类模板特化可能重构整体设计,复杂度更高。 影响: 函数模板:提升算法灵活性,维护简单,适合类型相关的

weixin_45422672的博客 1017

S7-1500 PLC与多台S7-200SMART PLC进行PROFINET通信的快捷方法

S7-1500 PLC与多台S7-200SMART PLC进行PROFINET通信的快捷方法

Robot_PLC_HMI_Automation 5687

Python 爬虫实战:付费 IP 代理使用技巧与爬虫稳定性优化

付费IP代理实战指南:突破反爬与优化稳定性 本文系统讲解付费IP代理在爬虫项目中的高效应用方法。首先对比分析静态代理、动态代理和隧道代理的优缺点及适用场景,推荐高并发项目优先选择隧道代理。然后详细演示了主流代理服务商的集成方法,包括代理池的自动更新和健康检测机制。核心部分重点介绍了爬虫稳定性优化策略,如智能重试、频率控制和请求间隔优化等关键技术。最后通过压力测试验证优化效果,并提供成本控制方案,包括代理复用、错峰爬取等实用技巧。通过本教程,开发者可有效解决高并发爬虫中的IP封禁问题,显著提升系统稳定性和抗风

2503_91057718的博客 2450

C++ 函数模板与重载规则

在C++编程中,函数模板和重载规则是提升代码复用性和灵活性的核心机制。函数模板允许开发者编写与数据类型无关的通用代码,而函数重载则通过同名函数的不同实现适应多样化需求。理解二者的交互规则,能够帮助开发者避免常见陷阱,写出更高效的代码。函数模板通过template关键字定义,用typename或class声明类型参数。例如,一个通用的交换函数模板可写作:template。C++函数模板与重载规则探秘。

aqcltq_267的博客 194

KNN算法

其原理是在给定的数据集中,根据某个距离度量方法,将测试数据与已知数据集中的所有数据进行距离计算,然后选取K个距离最近的数据作为测试数据的邻居,根据邻居的类别进行投票,将测试数据分类到得票最多的类别中。总之,KNN算法是一种简单而有效的分类方法,它不需要对数据进行训练,可以适用于多种数据类型和应用场景,并且可以通过调整K值或距离阈值等参数来控制算法的复杂度和性能。,KNN算法需要找到K个距离测试样本最近的训练样本,计算它们的类别,并将测试样本归入到得票最多的类别中。则取值为1,否则为0,表示邻居中属于类别。

优快云XXCQ的博客 2631

Win32 C++函数模板实战:泛型编程在传统GUI开发中的应用

泛型编程是C++的核心特性之一,它通过类型参数化实现了代码的高度复用。其基本原理是编写与具体类型无关的通用代码,编译器在编译时根据实际使用的类型自动生成特化版本,这一过程称为模板实例化。这种技术能显著提升代码的复用性和维护性,减少因类型不同而产生的冗余代码。在工程实践中,泛型编程尤其适用于处理模式相似但数据类型不同的操作,例如数据转换、算法封装和消息处理等场景。本文将结合Win32桌面开发,展示如何利用函数模板封装通用控件操作,如通过GetControlValue模板函数安全高效地获取编辑框的int、dou

weixin_30566111的博客 343

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

C++函数模板:泛型编程核心,告别重复代码,提升开发效率

泛型编程是C++中提升代码复用性和类型安全的核心范式,其核心思想是将数据类型参数化,从而编写出独立于具体类型的通用代码。函数模板作为泛型编程的基础工具,通过编译器在编译期根据实际调用类型自动生成特化版本,实现了“一次编写,多处使用”的目标。这种机制不仅大幅减少了代码冗余,还增强了类型安全性,避免了因手动复制粘贴导致的维护难题。在工程实践中,函数模板广泛应用于算法库(如排序、查找)、容器适配、数学运算等场景,能显著提升开发效率。本文深入解析函数模板的语法、实例化过程、参数推导机制,并探讨如何通过重载、特化等技

weixin_34389926的博客 311

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

C++函数模板:从泛型编程基础到实战进阶指南

泛型编程是一种编写与数据类型无关的通用代码的编程范式,其核心思想是通过参数化类型来提高代码的复用性和安全性。在C++中,这一理念主要通过模板技术实现,编译器在编译期间根据具体使用的类型自动生成对应的类型安全代码,从而避免了为不同数据类型重复编写相似算法的“造轮子”问题。这项技术不仅极大地提升了开发效率,降低了维护成本,更是构建C++标准模板库(STL)中`vector`、`sort`等组件的基石,对于实现高性能、高灵活性的库代码至关重要。其应用场景广泛,从简单的数据交换(`swap`)、比较(`max`)函

weixin_32175665的博客 231

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

C++函数模板:从基础语法到编译期多态的实战指南

泛型编程是现代编程语言中实现代码复用和类型安全的核心范式,其核心原理是通过参数化类型来创建可适用于多种数据类型的通用代码组件。在C++中,这一技术价值主要体现在编译期多态上,它允许在编译时根据具体类型生成特化代码,从而实现零运行时开销的类型抽象。函数模板作为泛型编程的基础设施,广泛应用于算法库、容器实现和通用工具函数等场景,能够有效解决代码冗余问题。通过理解模板参数推导、重载决议和SFINAE等机制,开发者可以构建出既灵活又高效的泛型组件,例如实现类型安全的通用算法或创建可扩展的库接口。本文深入探讨了函数模

weixin_30243533的博客 385

iOS培训必备——C++函数模板

蓝鸥iOS培训推荐:关于iOS开发必备课C++有关内容介绍,想必大家也对其有所了解吧!如果要想学好iOS开发、手游开发,都要从基础学起,从C、C++学起,那么今天趁有时间就和大家分享一下C++的函数模板。函数模板:事实上就是建立一个通用函数,其中函数类型和形参类型没有具体指定。用一个虚拟的类型代表这个通用函数。一般情况下,只要是函数体一样的函数都能够用这个模板代替,不用定义多...

weixin_34037977的博客 79

C++ Template 基础篇(一):函数模板

C++ Template 基础篇(一):函数模板Template所代表的泛型编程是C++语言中的重要的组成部分,我将通过几篇blog对这半年以来的学习做一个系统的总结,本文是基础篇的第一部分。C Template 基础篇一函数模板 为什么要有泛型编程 函数模板定义 普通函数模板 成员函数模板 为什么成员函数模板不能是虚函数virtual 实参推断 如何使用 当返回值类型也是参数时 实参推断时的自动类

lezardfu的专栏 15万+

C++ 函数模板基础

C++ 函数模板基础

英雄哪里出来 5074

C++ 模版基础知识——函数模板

C++ 函数模板是实现代码重用和类型安全的重要工具。通过使用模板,开发者能够编写通用的函数,这些函数可以处理多种数据类型,而无需为每种类型编写重复的代码。这种灵活性使得 C++ 在泛型编程方面具有显著优势。

慢慢记录,慢慢更新。 2050

C++函数模板

模板是一个通用框架,是C++泛型编程思想的主要体现。C++提供了函数模板和类模板两种模板机制,本文介绍的是函数模板相关的知识。

weixin_44205961的博客 5918

C++函数模板及实现原理

C++为我们提供了函数模板机制。所谓函数模板,实际上是建立一个通用函数,其函数类型和形参类型不具体指定,用一个虚拟的类型来代表。这个通用函数就称为函数模板。 凡是函数体相同的函数都可以用这个模板来代替,不必定义多个函数,只需在模板中定义一次即可。在调用函数时系统会根据实参的类型来取代模板中的虚拟类型,从而实现了不同函数的功能。     为什么要有函数模板     下面,我们就通过一个例子来说

常敲代码手不抖 2万+

深挖C++:类和对象(中)

(先进后出)

xys_678的博客 241
上一篇: 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、付费专栏及课程。

余额充值