网站建设资讯

NEWS

网站建设资讯

c语言模板函数实例化 c++函数模板特化

c++ 函数模板,实例化后,如何如何判断传入的数据类型?

数组参数属于指针参数.

创新互联公司一直在为企业提供服务,多年的磨炼,使我们在创意设计,全网整合营销推广到技术研发拥有了开发经验。我们擅长倾听企业需求,挖掘用户对产品需求服务价值,为企业制作有用的创意设计体验。核心团队拥有超过10年以上行业经验,涵盖创意,策化,开发等专业领域,公司涉及领域有基础互联网服务光华机房服务器托管重庆APP软件开发、手机移动建站、网页设计、网络整合营销。

指针参数即时传址参数(或叫引用参数), 如果想在函数中修改参数的值, 这是唯一的途径.

如果把数组当作参数, 不管你愿意与否, 它就是指针, 指向第一个值的指针.

1. 数组参数就是指向第一个元素的指针: #include stdio.h

void getArr(int p[], int si);

int main(void)

{

int ns[] = {1,2,3,4,5};

getArr(ns, sizeof(ns)/sizeof(ns[0]));

getchar();

return 0;

}

void getArr(int p[], int si) {

int i;

for (i = 0; i si; i++) {

printf("%d\n", p[i]);

}

}

2. 干脆直接声明为指针: #include stdio.h

void getArr(int *p, int si);

int main(void)

{

int ns[] = {1,2,3,4,5};

getArr(ns, sizeof(ns)/sizeof(ns[0]));

getchar();

return 0;

}

void getArr(int *p, int si) {

int i;

for (i = 0; i si; i++) {

printf("%d\n", p[i]);

}

}

3. 即使你在形参中指定维数也不起作用: #include stdio.h

void getArr(int p[2], int si);

int main(void)

{

int ns[] = {1,2,3,4,5};

getArr(ns, sizeof(ns)/sizeof(ns[0]));

getchar();

return 0;

}

void getArr(int p[2], int si) {

int i;

for (i = 0; i si; i++) {

printf("%d\n", p[i]);

}

}

4. 既然是指针, 其值就有被修改的可能: #include stdio.h

void getArr(int p[], int si);

int main(void)

{

int ns[] = {1,2,3,4,5};

size_t i;

getArr(ns, sizeof(ns)/sizeof(ns[0]));

for (i = 0; i sizeof(ns)/sizeof(ns[0]); i++) {

printf("%d\n", *(ns+i));

}

getchar();

return 0;

}

void getArr(int p[], int si) {

int i;

for (i = 0; i si; i++) {

p[i]++;

}

}

5. 如果是字符数组, 它自己能判断数组尾界: #include stdio.h

void getArr(char p[]);

int main(void)

{

char ns[] = "ABCDEFG";

getArr(ns);

getchar();

return 0;

}

void getArr(char p[]) {

int i;

for (i = 0; p[i]; i++) {

printf("%c: %d\n", p[i], p[i]);

}

}

查看模板实例化(c++)

其实无非两种,一种是具体化(又叫偏特化)一种是实例化(又叫全特话),对于具体化,就是

对模板的范围进一步压缩,并给这个更小的范围从新定义类成员(包括数据成员和方法)。对于实例化就是直接生成模板中某种实例(注意:同时给一个模板生成同一个实例化和具体化将报错)。举例:

#includeiostream

#includecstdio

#includestdlib.h

using namespace std;

template typename T1,typename T2//#1

class A

{

int a;

public:

A (){cout"this is AT1,T2 default constructor function!\n";}

};

template typename T1

class AT1,int//部分的具体化 #2

{

int b;

public:

A (){cout"this is AT1,int default constructor function!\n";}

};

template class Aint,char;//显示的实例化,将直接生成该类型类定义

int main()

{

class Aint ,int a;//隐式实例化 ,将隐式生成#2 的实例

class Aint ,char b; //隐式实例化,将隐式生成#1的实例

return 0;

}

关于c++ 函数的实例化和具体化的疑惑

我认为1不是实例化,而是函数模板的定义。所谓的实例化是指在编译或链接时生成函数模板或类模板的具体实例源代码。也就是通过函数模板生成模板函数的过程。

2应该是显式实例化,该行为发生在在编译链接后,函数调用前(隐式(implicit)实例化发生在函数调用后)。

3是显式具体化,这玩意的作用就一个:给特定的类型定义特定的操作。比如在你给的例子中,swap()只能被int型的模板函数调用,其他类型没这个操作。

函数void swap(int, int)只能被接受int型变量为参数,而模板函数可以接受任意类型变量为参数。

谁能帮我解释下C++函数模板显示实例化?

templateclass A

void fun(A a){}

template

void funint(int a){/*....*/}//显式具体化

void main()

{

float a=0;

funfloat(a);//显式实例化

}

模板在需要的时候才会实例化

在c语言中如何实现函数模板

各种用

C

语言实现的模板可能在使用形式上有所不同。现以一个求和函数

Sum

为例,用

C++

Template

可写如下:

template

R

Sum(const

T

*array,

int

n)

{

R

sum

=

0;

for

(int

i

=

;

i

n

;

++i)

sum

+=

i;

return

sum;

}

如果不是内置类型,该模板隐式地需要

有R

R::operator+=(T)运算符可用。

1.

使用函数指针作为

Functor

替换者

Typedef

struct

tagAddClass

{

Void

(*add)(char*

r1,

const

char*

r2);

Int

elemSize;

Char

sum[MAX_ELEM_SIZE];

}

AddClass;

void

Sum(AddClass*

self,

const

char*

array,

int

n)

{

for

(int

i

=

;

i

n

;

++i)

self-add(self-sum,

array

+

i*self-elemSize);

}

使用时:

Void

AddInt(char*

r1,

const

char*

r2)

{

*(long*)r1

+=

*(int*)r2;

}

AddClass

addClass

=

{AddInt,

2,

};

Int

array[100];

Read(array);

Sum(addClass,

array,

100);

…..

2.

用宏作为Functor的替换者

#define

GenSumFun(SumFunName,

Add,

RetType,

ElemType)

RetType

SumFunName

(const

ElemType

*array,

int

n)

\

{

RetType

sum

=

0;

for

(int

i

=

;

i

n

;

++i)

Add(sum,

i);

return

sum;

}

使用时:

#define

AddInt(x,

y)

((x)

+=

(y))

GenSumFun(SumInt,

AddInt,

long,

int)

…..

Int

array[100];

Read(array);

Long

sum

=

SumInt(array,

100);

…..

3.

所有可替换参数均为宏

至少需要一个额外的文件(实现文件)为

impsum.c

/*

impsum.c

*/

RetType

FunName(const

ElemType

*array,

int

n)

{

RetType

sum

=

0;

for

(int

i

=

;

i

n

;

++i)

Add(sum,

i);

return

sum;

}

使用时:

#undef

RetType

#undef

FunName

#undef

ElemType

#undef

Add

#define

AddInt(x,

y)

((x)

+=

(y))

#define

RetType

long

#define

FunName

SumInt

#define

ElemType

int

#define

Add

AddInt

#include

impsum.c

…..

Int

array[100];

Read(array);

Long

sum

=

SumInt(array,

100);

4.

总结:

第一种方法,易于跟踪调试,但是效率低下,适用于对可变函数(函数指针)的效率要求不高,但程序出错的可能性较大(复杂),模板函数(Sum)本身很复杂,模板参数也比较复杂(add)的场合。

第二种方法,效率高,但很难跟踪调试,在模板函数和模板参数本身都很复杂的时候更是如此。

第三种方法,是我最近几天才想出的,我认为是最好的,在模板参数(Add)比较复杂时可以用函数(第二种也可以如此),简单时可以用宏,并且,易于调试。在模板函数本身很复杂,而模板参数比较简单时更为优越。但是,可能有点繁琐。

C++函数模板的显示实例化有什么好处?我知道 显示具体化就是使它特殊化,显示实例化就是手动实例化?

明确实例化点。例如

template typename T

void f(T t) {

g(t);

}

class A{};

void g(const A a); // 函数1

template   void f(A t); // 显式实例化

void g(A a) { // 函数2

f(a); // 调用函数1,因为显式实例化时函数2 还没有声明

// 如果没有显式实例化则调用函数2,即无穷递归

}


分享题目:c语言模板函数实例化 c++函数模板特化
标题路径:http://njwzjz.com/article/hiciij.html