C++中typename与template

简介

在C++中最常见的这两个名称在模板中,不过其都有自己的特殊作用,帮助编译器通过代码编译,解决歧义问题

显示实例

#include 
#include 
#include 
#include 
#include 
//一个模板函数
template<typename T>
typename T::value_type my_sum(const T& cont)
{
	typename T::value_type res={};
	for(const auto& r : cont){
		res += r;
	}
	return res;
	/* cont.emplace(123);   */
	/* cont.template emplace(123)   */
}

int main()
{
	std::vector<int> ivals = {1,2,3,4,5};
	std::cout<< my_sum(ivals);	//15
	std::list<std::string> svals = {"hello","","world","!"};
	std::cout<<my_sum(svals);	//hello world
}

在上述事例中T::value_type用于返回容器内部存储的类型,但是与C不同,这种写法在编译的时候会产生歧义(可以是类型,也可以是成员,也可以是函数),导致你编译的时候不同通过,这个时候就要用typename明确的指定其是一个类型。

同理还有注释部分的调用

cont.emplace(123);
cont.template emplace<int>(123)

emplace是一个成员模板
第一种写法没有任何的问题,是一个直接的函数调用。但当需要显示的声明模板参数的时候就需要第二种写法,cont.template声明其是一个模板,不然会产生歧义。

  • 类模板的实例
typename T::template example<int>;

一般typename用的较多,其他的不是很常见

emplace,emplace_front,emplace_back

针对顺序容器(vector,deque,list)引入的三个新成员,分别对应insert,push_front,push_back。这些操作构造而不是拷贝元素

时,则是将参数传递给元素类型的构造函数。emplace成员使用这些参数在容器管理的内存空间中直接构造元素。

emplace函数的参数根据元素类型而变化,参数必须与元素类型的构造函数相匹配。emplace函数在容器中直接构造元素。传递给emplace函数的参数必须与元素类型的构造函数相匹配。

其它容器中,std::forward_list中的emplace_after、emplace_front函数,std::map/std::multimap中的emplace、emplace_hint函数,std::set/std::multiset中的emplace、emplace_hint,std::stack中的emplace函数,等emplace相似函数操作也均是构造而不是拷贝元素。

emplace相关函数可以减少内存拷贝和移动。当插入rvalue,它节约了一次move构造,当插入lvalue,它节约了一次copy构造。

你可能感兴趣的:(C++,c++,开发语言,后端)