波奇学C++:C++11的可变参数模板和emplace

 可变参数模板

// args是参数包
template<class T,class ...Args>
void _ShowList(T value, Args... args)
{
	cout << sizeof...(args) << endl; // 2
	cout << value << " ";
	/*_ShowList(args...);*/
	
}
int main()
{
    _ShowList(1,2,3); 
    return 0;
}

可变参数类型模板指的是参数的类型和数量是可变的。在上面的代码,Args是个参数包可以接收多个多个参数。底层是以数组接收参数。

如何查看参数包args中的参数。args的范围是0到1。

template<class T>
void _ShowList(T val)
{
	cout << val << " ";
	cout << endl;
}

template<class T,class ...Args>
void _ShowList(T value, Args... args)
{
	cout << sizeof...(args) << endl;
	cout << value << " ";
	_ShowList(args...);
	
}

通过函数重载,一个个参数拿出来看。

方式二

template<class T>
int PrintArg(T t)
{
	cout << t << " ";
	return 0; 
}
template<class ...Args>
void CppPrint(Args... args)
{
	int a[] = { PrintArg(args)... };
}
int main()
{
	CppPrint(1,2,3,4,5,6);
	return 0;
}

这个的原理是PrintArg(args)... 会扩展看来相当于下面

int a[]={PrintArg(1), PrintArg(2), PrintArg(3),PringArg(4),...};

可变模板参数模板在初始化对象的使用 

class Date
{
public:
	Date(int year, int month, int day)
		:_year(year)
		, _month(month)
		, _day(day)
	{
		cout << "构造函数";
	}
private:
	int _year;
	int _month;
	int _day;
};
template<class ...Args>
Date* create(Args... args)
{
	Date* p = new Date(args...);
	return p;
}
int main()
{
	create(1, 0, 9);
	return 0;

}

在上面的代码中 create函数接收的1,0,9的值存进了args,args...拓展出来分别初始化对应参数。

 容器的emplace接口的参数就是可变参数模板。

 

 

 

 我们可以看到mylist.emplace_back只调用了string的构造函数,而mylist.push_back()只能先调用了string构造出pair,pair进行insert再进行push_back再进行移动拷贝构造。

实际上因为右值引用,所以其实emplace和push效率上没有太大区别。

默认的移动构造函数生成

针对移动构造函数和移动赋值运算符重载有一些需要注意的点如下:

如果你没有自己实现移动构造函数,且没有实现析构函数、拷贝构造、拷贝赋值重载中的任意一个。那么编译器会自动生成一个默认移动构造。默认生成的移动构造函数,对于内置类型成员会执行逐成员按字节拷贝,自定义类型成员,则需要看这个成员是否实现移动构造,如果实现了就调用移动构造,没有实现就调用拷贝构造

如果你没有自己实现移动赋值重载函数,且没有实现析构函数、拷贝构造、拷贝赋值重载中的任意一个,那么编译器会自动生成一个默认移动赋值。默认生成的移动构造函数,对于内置类型成员会执行逐成员按字节拷贝,自定义类型成员,则需要看这个成员是否实现移动赋值,如果实现了就调用移动赋值,没有实现就调用拷贝赋值。(默认移动赋值跟上面移动构造完全类似)

如果你提供了移动构造或者移动赋值,编译器不会自动提供拷贝构造和拷贝赋值。


class Date
{
public:
	Date(int year, int month, int day)
		:_year(year)
		, _month(month)
		, _day(day)
	{
		cout << "构造函数";
	}
	Date(Date&& p) = default; //强制生成移动构造
	Date(const Date& p) = default; //强制生成拷贝构造
private:
	int _year;
	int _month;
	int _day;
};

  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值