栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

《C++11标准库》3.2 Template虽旧犹新的语言特性

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

《C++11标准库》3.2 Template虽旧犹新的语言特性

Nontype Template Parameter(非类型模板参数)

Type parameter(类型参数)之外,我们也可以为 template 使用 nontype parameter(非类型参数)。这样的参数亦被视为 template 类型的一部分。例如对于标准的 class bitset<>,你可以传递bit 个数为实参。例如:

bitset< 32 > flags32 ;// 32bits 的 bitset
bitset< 50 > flags50 ;// 50bits 的 bitset

对于上述 bitset 有着不同的类型,因为它们使用不同的 template 实参。因此,不能对上述二者进行赋值或者比较等操作,除非它们之间有一个相应的类型转换。

Default Template Parameter(模板参数默认值)

Class template 可以拥有默认实参。例如下述的声明式,允许我们在声明 class MyClass 对象时指定 1 或 2 个 template 实参;

template < typename T ,typename container = vector >

class MyClass;

 

 如果只对 MyClass 传入一个实参,则第二实参会采用默认值,且 template 实参可根据前一个实参为依据而定义。例如

Myclass< int > x1; //实际参数为 MyClass< int , Vector< int> >

 关键字 typename

关键字 typename 用来指明紧跟其后的是个类型。例如:

class Q
{

public:
	typedef int SubType;
};

template 
class MyClass
{
	typename T::SubType* ptr;
};

在上述例子中,typename 被用来阐明“ SubType 是一个定义于 class T 中的类型”,因此,ptr 的类型为一个指向 T::SubType类型的指针,即一个 int 型指针。

对于 SubType 也可以是一个抽象类型,例如一个 class :

class Q
{
public:
	class SubType;
};

template 
class MyClass
{
	typename T::SubType* ptr;
};

int main()
{
	MyClass z;
	return 0;
}

Member Template(成员模板)

class 的成员函数可以是 template。然而 member template 不可以是 virtual。例如

class MyClass
{
	template
	void f(T);
};

对于上述代码中 M有Class:: f()声明了“一组”成员函数,其参数类型可以是任意类型。你可以通过传递任何实参给它们,只要该实参提供了“ f() 用到的所有操作”。

这一语言特性往往被用来支持 class template 内的成员之间的自动类型转换。例如下列的定义式中,assign() 的实参 x 必须和 value 的类型完全相同。(两个对象的类型相同)

template 
class MyClass
{
private:
	T value;
public:
	void assign(const MyClass& x)//x必须有和value相同的类型,即为 *this
	{
		value = x.value;
	}
};

如果 assign 的调用者(value)与其实参(x)template 类型不同,是不被允许使用的,即便提供了类型之间的转换。

void f()
{
	MyClass d;
	MyClass x;
	d.assign(d);
	d.assign(x);//不存在从 MyClass到const MyClass的转换
}

但是,如果提供一个不一样的 template 类型,你就可以从“必须精确吻合”的规则中解脱。例如下属例子中,这个成员函数的 template 实参可以为任何 template 类型,只要该类型“可被赋值”:

template 
class MyClass
{
private:
	T value;
public:
	template
	void assign(const MyClass& x)//修改处::可以接受任意类型 template 类型参数
	{
		value = x.getValue();
	}

	T getValue()const
	{
		return value;
	}
};

则对于之前的操作便是可行的:

void f()
{
	MyClass d;
	MyClass x;
	d.assign(d);
	d.assign(x);//  d的类型为double
}

特别注意,对于修改之后的模板,assign() 的实参 x ,其类型不同于 *this 的类型,因此我们不能直接取用 MyClass<>的 private 和 protected 成员。如果想使用这些成员,你需要它提供一个函数例如:T  getValue() ;

Member template 的一个特殊形式是所谓的 template 构造函数。这种东西通常被提供用于“对象被复制时给予的隐式类型转换”能力。但是对于 template 构造函数并不会压制 copy 构造函数的隐式声明,如果类型完全吻合,则会调用 copy 构造函数。例如,如果含有copy 构造函数

void f()
{
	MyClass d;
	MyClass x;
	d.assign(d); //调用 copy 
	d.assign(x);// 调用 member template
}

 

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/854219.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号