文章目录

  • enum枚举类型
  • decltype
  • 引用
  • 成员初始化列表
  • initializer_list列表初始化


 

enum枚举类型

限定作用域的枚举类型

enum class open_modes{intput, output, append};

不限定作用域的枚举类型

enum color{red, yellow, green};
enum {floatPrec=6, doublePrec=10};

decltype

decltype关键字用于检查实体的声明类型或表达式的类型及值分类。语法:

decltype (expression)

decltype的使用

//尾置返回允许我们在参数列表之后声明返回类型
template <typename It>
auto fcn(It beg, It end) -> decltype(*beg)
{
	//处理序列
	return *beg;//返回序列中一个元素的引用
}
//为了使用模板参数成员,必须用typename
template <typename It>
auto fcn2(It beg, It end) -> typename remove_reference<decltype(*beg)>::type
{
	//处理序列
	return *beg;//返回序列中一个元素的拷贝
}

引用

左值引用
常规引用,一般表示对象的身份。
右值引用
右值引用就是必须绑定到右值(一个临时对象、将要销毁的对象)的引用,一般表示对象的值。
右值引用可实现转移语义(Move Semantics)和精确传递(Perfect Forwarding),它的主要目的有两个方面:
消除两个对象交互时不必要的对象拷贝,节省运算存储资源,提高效率。
能够更简洁明确地定义泛型函数。
引用折叠
X& &X& &&X&& &可折叠成X&X&& &&可折叠成X&&

宏定义可以实现类似于函数的功能,但是它终归不是函数,而宏定义中括弧中的“参数”也不是真的参数,在宏展开的时候对“参数”进行的是一对一的替换。

成员初始化列表

好处
更高效:少了一次调用默认构造函数的过程。
有些场合必须要用初始化列表:
常量成员,因为常量只能初始化不能赋值,所以必须放在初始化列表里面
引用类型,引用必须在定义的时候初始化,并且不能重新赋值,所以也要写在初始化列表里面
没有默认构造函数的类类型,因为使用初始化列表可以不必调用默认构造函数来初始化。

initializer_list列表初始化

用花括号初始化器列表初始化一个对象,其中对应构造函数接受一个std::initializer_list参数。
initializer_list使用

#include<iostream>
#include<vector>
#include<initializer_list>

template<class T>
struct S{
	std::vector<T> v;
	S(std::initializer_list<T> l) : v(l){
		std::cout << "constructed with a " << l.size() << "-element list\n";
	}
	void append(std::initializer_list<T> l){
		v.insert(v.end(), l.begin(), l.end());
	}
	std::pair<const T*, std::size_t> c_arr() const{
		return {&v[0], v.size()};	//在return语句中复制列表初始化
									//这不使用std::initializer_list 
	}
};
template <typename T>
void templated_fn(T) {}

int main()
{
	S<int> s = {1, 2, 3, 4, 5};		//复制初始化 
	s.append({6, 7, 8});			//函数调用中的列表初始化 

	std::cout<<"The vector size if now " << s.c_arr().second << " ints:\n";
	
	for(auto n : s.v)
		std::cout << n << ' ';
	std::cout << '\n';

	std::cout << "Range-for over brace-init-list: \n";

	for(int x : {-1, -2, -3})
		std::cout << x << ' ';
	std::cout<<'\n';

	auto al = {10, 11, 12};			//auto的特殊规则 
	
	std::cout<<"The list bound to auto has size() = " <<al.size() << '\n';

//	templated_fn({1, 2, 3});		//编译错误! "{1, 2, 3}"不是表达式,
									//它无类型,故T无法推导 
	templated_fn<std::initializer_list<int>>({1, 2, 3});	//OK 
	templated_fn<std::vector<int>>({1, 2, 3});				//也OK 
}