在C语言中实现模板函数的方法

合集下载

C++11模板元编程-std::enable_if示例详解

C++11模板元编程-std::enable_if示例详解

C++11模板元编程-std::enable_if⽰例详解C++11中引⼊了std::enable_if函数,函数原型如下:template< bool B, class T = void >struct enable_if;可能的函数实现:template<bool B, class T = void>struct enable_if {};template<class T>struct enable_if<true, T> { typedef T type; };由上可知,只有当第⼀个模板参数为true时,enable_if会包含⼀个type=T的公有成员,否则没有该公有成员。

头⽂件:#include <type_traits>std::enable_if使⽤场景1、限制模板函数的参数类型在某些场景下,我们需要实现只有特定类型可以调⽤的模板函数。

如下代码所⽰,通过对返回值使⽤std::enable_if和在模板参数中使⽤std::enable_if均实现了只允许整形参数调⽤函数的功能。

// enable_if example: two ways of using enable_if#include <iostream>#include <type_traits>// 1. the return type (bool) is only valid if T is an integral type:template <class T>typename std::enable_if<std::is_integral<T>::value,bool>::typeis_odd (T i) {return bool(i%2);}// 2. the second template argument is only valid if T is an integral type:template < class T,class = typename std::enable_if<std::is_integral<T>::value>::type>bool is_even (T i) {return !bool(i%2);}int main() {short int i = 1; // code does not compile if type of i is not integralstd::cout << std::boolalpha;std::cout << "i is odd: " << is_odd(i) << std::endl;std::cout << "i is even: " << is_even(i) << std::endl;return 0;}当使⽤float类型参数调⽤函数时,程序会报错:error: no matching function for call to 'is_odd(float&)'2. 模板类型偏特化在使⽤模板编程时,可以利⽤std::enable_if的特性根据模板参数的不同特性进⾏不同的类型选择。

c函数指针的模板声明和定义 -回复

c函数指针的模板声明和定义 -回复

c函数指针的模板声明和定义-回复C函数指针的模板声明和定义C函数指针是一种特殊类型的指针,它指向一个函数而不是指向一个变量。

函数指针可以将函数作为参数传递给其他函数,也可以将函数作为返回值返回。

在C语言中,函数指针可以通过模板声明和定义来使用。

一、函数指针的模板声明在C语言中,函数指针的模板声明可以通过使用typedef关键字来实现。

typedef关键字可以创建一个用于定义函数指针的新类型。

下面是一个示例:typedef int (*FunctionPointer)(int, int);这个例子中,我们创建了一个新类型的函数指针,名为FunctionPointer。

FunctionPointer指针指向一个接受两个整数参数并返回一个整数结果的函数。

二、函数指针的模板定义函数指针的模板定义涉及到具体的函数以及如何使用它们。

函数指针定义的语法是将函数指针作为参数传递给其他函数或将其作为返回值返回。

下面是一个示例:int add(int a, int b) {return a + b;}int subtract(int a, int b) {return a - b;}int calculate(int a, int b, int (*func)(int, int)) {return func(a, b);}在这个例子中,我们定义了两个用于执行简单数学运算的函数:add函数和subtract函数。

我们还定义了一个calculate函数,它接受两个整数参数a和b,以及一个函数指针参数func。

calculate函数可以根据func参数的值来执行不同的数学运算。

我们可以通过将add函数或subtract函数作为func参数传递给calculate函数来执行相应的加法或减法运算。

三、使用函数指针的模板声明和定义使用函数指针的模板声明和定义可以实现更加灵活和复杂的程序逻辑。

函数指针可以作为参数传递给其他函数,也可以作为返回值返回。

7&8

7&8
12
用类模版完成两个数比较程序: 运行结果:
7 is the Max. 3 is the Min. 93.6 is the Max. 45.78 is the Min. a is the Max. A is the Min.
void main( ) { Compare <int> cmp1(3,7); cout<<cmp1.max( )<<″ is the Max.″<<endl; cout<<cmp1.min( )<<″ is the Min.″<<endl<<endl; Compare<float> cmp2(45.78, 93.6); cout<<cmp2.max( )<<″ is the Max.″<<endl; cout<<cmp2.min( )<<″ is the Min.″<<endl<<endl; Compare<char> cmp3(′a′,′A′); cout<<cmp3.max( )<<″ is the Max.″<<endl; cout<<cmp3.min( )<<″ is the Min.″<<endl; }
增加友元运算符==重载函数模板:程序7-2头文件ex7_2.h:
class CComplex { public: …… template <class T> friend bool operator==(const T &r_a, const T &r_b); }; #include <iostream.h> #include "ex7_2.h" …… template <class T> bool operator==(const T &r_a, const T &r_b) { if (r_a.real == r_b.real && r_a.image == r_b.image) return true; else return false; } void main() { …… if (c1 == c2) cout << "they are equal\n"; else cout << "they are not equal\n"; }

模板类构造函数_0

模板类构造函数_0

模板类构造函数篇一:C#类的构造函数与析构函数C#类的构造函数与析构函数1. 构造函数:类的构造函数是用来创建类的一个实例。

创建一个实例的一般形式:类名实例名= new 类名(构造函数参数列表);构造函数和类中其他函数相比,是较为特殊的,它的名称必须和类同名。

定义一个构造函数的一般形式是:Class 类名{类名(参数表);//就是定义构造函数{//语句}}例子:using System;class MyClass{MyClass(){Console.WriteLine(启动构造函数);Console.ReadLine();}public static void Main(){MyClass cM = new MyClass();}}运行结果:MyClass()就是一个构造函数,构造函数是没有任何返回值的。

构造函数也可以携带参数,看下面的例子:using System;class userName{string Uname;//定义一个带参数的构造函数public userName(string name){Console.WriteLine(新建一个用户:);Uname = name; }public void ShowName(){Console.WriteLine(用户名是:+ Uname); }public static void Main(){//用带参数的构造函数创建类的一个实例userName uN1 = new userName(zhanghua);uN1.ShowName();Console.ReadLine();}}运行结果:2. 析构函数定义一个析构函数的一般形式是:Class 类名{~类名(参数表);//定义析构函数{//语句}}析构函数的使用:using System;class First{public First(){Console.WriteLine(First&#39;s constructor is called);}~First(){Console.WriteLine(First&#39;s destructor is called);}}class Second{public Second(){Console.WriteLine(Sencond&#39;s constructor is called); }~Second(){Console.WriteLine(Second&#39;s destructor is called);}}class Third{public Third(){Console.WriteLine(Third&#39;s constructor is called);}~Third()篇二:11级C++综合习题(含答案)一、单项选择题1. 函数重载是指( A )。

s function c代码 标准模板

s function c代码 标准模板

s function c代码标准模板S函数是一种常用的非线性函数,它经常在系统建模、数据拟合和优化等领域中使用。

在C代码中,我们可以通过定义一个函数来实现S函数的功能。

本文将介绍如何使用C语言实现S函数的标准模板。

标准的S函数模板可以通过以下代码实现:```c#include <math.h>double sFunction(double x, double a, double b){return 1 / (1 + exp(-a * (x - b)));}```这段代码定义了一个名为" sFunction "的函数,接受三个参数:x、a和b。

其中,x表示输入变量,而a和b则是S函数的参数。

函数的返回值为S函数的计算结果。

函数的实现主要依赖于C语言的数学库" math.h "中的指数函数" exp "。

在实际应用中,我们可以根据具体需求对S函数的参数进行调整,从而得到不同形状和范围的曲线。

下面是一个简单的示例,演示了如何使用这个S函数来计算给定输入变量x的输出值:```c#include <stdio.h>int main(){double x = 2.0;double a = 1.0;double b = 0.0;double result = sFunction(x, a, b);printf("S function result: %f\n", result);return 0;}```在这个示例中,我们将输入变量x设置为2.0,参数a设置为1.0,参数b设置为0.0。

然后,我们调用sFunction函数来计算S函数的输出值,并通过printf函数将结果打印到屏幕上。

编译并运行上述代码,我们可以得到如下输出:```S function result: 0.880797```这是根据给定的输入变量x和S函数参数计算出的S函数结果。

c设计一个函数模板求

c设计一个函数模板求

c,,设计一个函数模板求篇一:程序设计之模板c语言相关目录1 前言 ................................................ . (1)2 需求分析 ................................................ (1)要求 ................................................ .. 1任务 ................................................ .. 1运行环境 (1)开发工具 (1)3 概要设计与详细设计 (1)系统流程图 (1)查询函数流程图 (2)4 编码与实现 .................................................2分析 ................................................ .. 2具体代码实现 (3)5 课程设计总结 (3)参考文献 ................................................ .. (3)致谢 ................................................ (3)1 前言编写一个程序来处理同学通信录。

通过一个结构体数组来存放输入的每一位同学的记录(包括姓名、电话号码、e_mail、地址),然后将其信息存入文件中。

输入一个姓名查询该同学的信息,并显示在屏幕上。

2 要求(1)用C语言实现程序设计;(2)利用结构体进行相关信息处理;(3)画出查询模块的流程图;(4)系统的各个功能模块要求用函数的形式实现;(5)界面友好(良好的人机互交),程序要有注释。

任务(1)定义一个结构体类型数组,输入每一位同学的记录(包括姓名、电话号码、e_mail、地址),将其信息存入文件中;(2)输入姓名查询该同学的信息,并显示在屏幕上;(3)画出所有模块的流程图;(4)编写代码;(5)程序分析与调试。

C语言程序设计期末练习(填空题)

C语言程序设计期末练习(填空题)

面向对象程序设计期末综合练习二〔填空题〕填空题1. C++语言是在_________语言的根底上开展起来的。

2. C++语言的编译单位是扩展名为__________的__________文件。

3. 行尾使用注释的开场标记符为__________。

4. 多行注释的开场标记符和完毕标记符分别为__________和__________。

5. 用于输出表达式值的标准输出流对象是_________。

6. 用于从键盘上为变量输入值的标准输入流对象是________。

7. 一个完整程序中必须有一个名为________的函数。

8. 一个函数的函数体就是一条_________语句。

9. 当执行cin语句时,从键盘上输入每个数据后必须接着输入一个________符,然后才能继续输入下一个数据。

10. 在C++程序中包含一个头文件或程序文件的预编译命令为__________。

11. 程序中的预处理命令是指以______字符开头的命令。

12. 一条表达式语句必须以______作为完毕符。

13. 在#include命令中所包含的头文件,可以是系统定义的头文件,也可以是________定义的头文件。

14. 使用#include命令可以包含一个头文件,也可以包含一个______文件。

15.一个函数定义由________和________两局部组成。

16.假设一个函数的定义处于调用它的函数之前,则在程序开场可以省去该函数的______语句。

17.C++头文件和源程序文件的扩展名分别为______和______。

18.程序文件的编译错误分为________和________两类。

19.当使用_______保存字作为函数类型时,该函数不返回任何值。

20.当函数参数表用______保存字表示时,则表示该参数表为空。

21.从一条函数原型语句“int fun1(void);〞可知,该函数的返回类型为______,该函数带有______个参数。

关于VC语言中类的继承与模板的实例分析

关于VC语言中类的继承与模板的实例分析
维普资讯
信息 科 学 Il ;

关于 V C语言中类的继承与模板的实例分析
( 盐城 工学院, 江苏 盐城 2 40 ) 20 0
摘 要: 的 承与 板 C 言中 难 和 点 在 入学 C 的 承 模板 帮 我 好学 好V. 并 行大 类 继 模 是V 语 的 点 重 。 深 习V 类 继 与 可 助 们更 鼍 c 语
Sa k me e : tc mb r . 可简化了程序设计方法 ,显著提高软件的重用 以下为具体步骤 : 3 ( ) 基类 Ln L tLn Ls的实现类 I I 一 设计 i i。 i i k s k t 性, 叉使得软 件更容易维护 。 派生则是继承的直 用链表结构实现。 要求 I2 I 接产物 , 通过继承 已有 的—个或多个类来生一 似于实验五中的队列类 , 1 () 个新类 , 通过派生可创建一种类族 。它的实现 , 链表类具有以下 功能: 1能够在链表的头尾增 I I l 2 方便 了更大规模 的软件开发。因而类 的继承与 加节点 以及在链表头删除节点( )能够记录链 IO 用静 态成员 )3 能返 回链表 中 的节 () 模板 在类 的学习 中极其重要。下面我们具体谈 表 的个数 ( 点个数( ) 4 能查看链 表头节点的元素值( ) 5 能告 谈类及类 的继承与模板 。 f 用多文 件结构实现 程序。三个类 的定 4 ) 6 在链 表 在 VC中,这种将数据与处理这些 数据 的 知链表是否 为能告知链表是否为 空( ) 7 在链 表类 的析 义放在一个头文件中 , 的实现放在另一个 源 类 函数封装成—个整体 , 就构成一个类。或者说 , 类 的构造 函数 中初始化链表 ( ) 类 是对一组性质相 同事物 的程序描述 ,它由描 构函数中释放链表所有元素的空间。下面给出 文件中。主程序用于测试你所设计的三个类 的 测试内容包括如下 :) 队列 中加入几 1在 述该类事 物的共 同特性 的数据和处理这些数据 链 表类 的类定 义 ,我 们可 据定义 完全 实现该 正确性 。 个元 素 , p nQ ee 打 印队列 内容 , 用 r t uu 0 i 然后 再 的函数组成 。 一个类 可以根据需要 生成派生类 。 类 。 从队列 中取 出这些元素 , 看是否 正确 2 在栈 中 ) , 用链表实现的列 表类 个 派生类又可 以作为另—个 类的基类 , 一个 , 加入几个 元素 , p nS e 0 印栈 的内容, 用 r tak打 i t 然 基类可 以派生出若干个 派生类 , 这样可 以构成 casLn Ls I ls ik i t 后再从栈中取 出这些元素 , 看是否正确 3 测试 ) 定义链表节点类 型 了类树 。 继承常用来表示类属关系。 当从 已有 的 , , 取 队列 长度 的 函数 gt uuL n t 的正确 性 e e e eg 0 Q h 类 中派生 出新的类时 , 可对派生类傲几种变化 : tpd fsrc nd I yee t t oe u n a 4 测试 判断栈 是否 为空 的函数 e p 0 ) m t 的正确 y ( )可全部或部分地继承基类 的成员数据或成 i t d m; 1 性。 员 函数( ) 2 可增加新 的成员变量 ( ) 3可增加新 的 src o e n x tu tn e d ( 实 现提示 四) 成员 函数( ) 4 可重定义已有的成员 函数( ) 5 可改 }Ls aa o e it t d ; D N ( 1 )链表类的实现可 以参考实验五中 队列 变现有的成员属性 。 c + 在 + 中有两种继承 : 单一 , 义链表类 型 , 定 y  ̄ it tNo i t t; 类 的实现 。()测试 程序可 以用如下程序 : 2 继承( 一个派生类仅 由一个 基类派生 ) 和多重继 tp fL sDaa d e L sDaa 衢 n l d < o te m.> c u e i sr a h 承 ( 一个 派生类 由两个或更多个基类所派生 ) p oe t d 。 rtce : 衔n l d ”i l s. ” c u e l dit n h 派生类继 承了基类 的所有方法 ,另外派生类 自 itc ut _ n on; I J 表中元素的个数 it t aa n ed aa i a ;表头 、 D Lk k l, 表 vi an 身还 可定义所 需要 的不包 含在 父类 中 的新 方 Ls aa d t i H a .dtLnT i, o m i0 I d 法。 而模板是 c + + 语言—个重要特征。 模板使程 尾 指 针 Q ee q u u l= nw Q ee e u u; Sa k * l : n w tc ; tc s e Sa k t i Ls o n;/ 表个数 ac t 7 序员快速 建立具有类型安全 的类库集合和函数 s t i C u t /4 cu o t<< ’ .lJLit: < Ln Litg t sNu ’0丑 ss“ < ik s: eLit m— 1 : 集合。 它的实现 。 方便 了更大规 模的软件开发 。 p b c uh: 模 板也是 c + + 语言支持参 数化多态性 的工具 。 Ln Lsvi) , 造 函 数 ik it o ; , ( d 构 bm < nl 腧 出总 的列表数 e <e d; 将一段程序所处理的对象类型参 数化,就可 以 vr a Ln Ls vi) 晰 构 函数 iul— ik i(od;, t t f iti: O o n r( ;j<4 i+ , 队列 和栈中加 ;+) , 在 使这段程序能够处理某个类型范围内的各种类 vi p tal ( tnwD t) od uTi i e a ;们笙 尾加入一个 入 元 素 n a 表 型 的对象 , 这就是参数化多态性 。 被参数化 的一 新 元素 f1 > n uu (; q - e Q eei ) 段程序将会处理一定 范围内的若 干种不 同类型 vi uH a itnwD t) od p ted( e a ;们笙 头插入一个 s一 ps(; n a 表 l > uhi ) 的对象 ,即对 于一定 范围内的若干不 同类型 的 新 元素 ) 对象 的某种 操作将对 应 着一个 相 同结构 的实 it e ed( i ; / n gt a v d / H o ) 从表头取 出一个元素 tu < ” u u lnt: < q - gtu u — o t< Q e e e g ” ‘ l >eQ e e h 现。 而模 板这种工具就是用来解决这个问题 的。 i ek ed o ); 看表头 元素的值 , n peHa( i , t vd 鹰 假定 L n t 0< nl , 出队列 长度和队列中元 eg <e d 墒 h ; 下面 可以通 过设计 一个基类 , 完成 队列 和 列表至少有一个 元素 素个数 栈共 同的功 能,然后分别派生 出队列类和栈类 bo m t ;/ ole py() / 检查列 表是 否空 q 一 pi Q e e ; 腧 出栈 的内容 l > r t uu0 n 这两个派生类 。 这样可减少代码 , 提高效率 。 设 i e l C u t ;, n gt e o n t E m 0 , 取列表元素个 数 cu < ”tc o :”< s- tp < ed; ot< S k tp a < l >o0 < nl 计 的基类也可 以用于派生 出其他类。本 实例要 s t n eLs u e0 , ti itgtit mbr ;, ac N 取列 表个 数 s一 pitte0 / 出队列和栈中的元素 l > r Sak ; / �
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
各种用C语言实现的模板可能在使用形式上有所不同。现以一个求和函数Sum为例,用C++ Template可写如下:
template R Sum(const T *array, int n)
{
R sum = 0;
for (int i = 0 ; i < n ; ++i)
sum += i;
return sum;
{
*(long*)r1 += *(int*)r2;
}
AddClass addClass = {AddInt, 2, 0 };
Int array[100];
Read(array);
Sum(&addClass, array, 100);
…..
2.用宏作为Functor的替换者
#define GenSumFun(SumFunName, Add, RetType, ElemType) \
第三种方法,是我最近几天才想出的,我认为是最好的,在模板参数(Add)比较复杂时可以用函数(第二种也可以如此),简单时可以用宏,并且,易于调试。在模板函数本身很复杂,而模板参数比较简单时更为优越。但是,可能有点繁琐。
一般情况下,没有必要做如此劳心的工作,一切交给编译器去做就行了。但是本人在开发一个文件系统时,由于是基于一种少见的平台,没有可用的C++编译器,有几个函数,除了其中的类型不同(uint16和uint32),和几个可参数化的宏不同,其它地方完全相同,而函数本身很复杂(两百多行代码)。Copy出几个完全类似的函数副本,维护起来特别烦人。非常需要如此的编程模式,故此,分享出来,大家共同探讨。
} AddClass;
void Sum(AddClass* self, const char* array, int n)
{
for (int i = 0 ; i < n ; ++i)
self->add(self->sum, array + i*self->elemSize);
}
使用时:
…..
Void AddInt(char* r1, const char* r2)
}
如果不是内置类型,该模板隐式地需要有R R::operator+=(T)运算符可用。
1.使用函数指针作为Functor替换者
Typedef struct tagAddClass
{
Void (*add)(char* r1, const char* r2);
Int elemSize;
Char sum[MAX_ELEM_SIZE];
GenSumFun(SumInt, AddInt, long, int)
…..
Int array[100];
Read(array);
Long sum = SumInt(array, 100);
…..
3.所有可替换参数均为宏
至少需要一个额外的文件(实现文件)为impsum.c
/* impsum.c */
#undef Add
#define AddInt(x, y) ((x) += define FunName SumInt
#define ElemType int
#define Add AddInt
#include impsum.c
…..
Int array[100];
RetType SumFunName (const ElemType *array, int n) \
{ \
RetType sum = 0; \
for (int i = 0 ; i < n ; ++i) \
Add(sum, i); \
return sum; \
}
使用时:
#define AddInt(x, y) ((x) += (y))
RetType FunName(const ElemType *array, int n)
{
RetType sum = 0;
for (int i = 0 ; i < n ; ++i)
Add(sum, i);
return sum;
}
使用时:
#undef RetType
#undef FunName
#undef ElemType
Read(array);
Long sum = SumInt(array, 100);
…..
4.总结:
第一种方法,易于跟踪调试,但是效率低下,适用于对可变函数(函数指针)的效率要求不高,但程序出错的可能性较大(复杂),模板函数(Sum)本身很复杂,模板参数也比较复杂(add)的场合。
第二种方法,效率高,但很难跟踪调试,在模板函数和模板参数本身都很复杂的时候更是如此。
相关文档
最新文档