C++2.0——explicit、decltype、nullptr、auto 和 for循环

explict

在 c++2.0之前,一个参数的构造函数(或者除了第一个参数之外其余参数都有默认值的多参构造函数),承担着两个作用:1. 构造器2. 隐含的类型转换操作符;而explicit关键字一直存在,只能作用在构造函数中, 目的是阻止编译器进行不应该允许的构造函数进行隐式转换。

而在C++2.0中,explicit可以支持不止一个参数的构造函数使用。

#include <iostream>
using namespace std;


struct A
{
	A(int) 
	{
		cout << "A::A(int)" << endl;
	}      
	A(int, int)
	{
		cout << "A::A(int,int)" << endl;
	}
};

struct B
{
	explicit B(int) 
	{
		cout << "B::B(int)" << endl;
	}
	explicit B(int, int) 
	{
		cout << "B::B(int,int)" << endl;
	}

};

int main()
{
	A a1 = 1;      
	A a2(2);       
	A a3{ 4, 5 };   
	A a4 = { 4, 5 }; //c++2.0 可以支持多个参数的隐式转换
	A a5 = (A)1; 
	

	//B b1 = 1; //error C2440: “初始化”: 无法从“int”转换为“B” ,explicit禁止了隐式转换     
	B b2(2);       
	B b3{ 4, 5 };  
	//B b4 = {4, 5}; // error C2440: “初始化”: 无法从“initializer list”转换为“B”
	B b5 = (B)1;

	return 0;
}

auto

C++11 auto可以在声明变量的时候根据变量初始值的类型自动为此变量选择匹配的类型,auto的自动类型推断发生在编译期,所以使用auto并不会造成程序运行时效率的降低,auto和其他变量类型有明显的区别:

  • auto声明的变量必须要初始化,否则编译器不能判断变量的类型。
  • auto不能被声明为返回值,auto不能作为形参,auto不能被修饰为模板参数。
  • auto用于代替冗长复杂、变量使用范围专一的变量声明。

template<typename _Iterator>
#if __cplusplus < 201103L
inline typename reverse_iterator<_Iterator>::difference_type
    operator-(const reverse_iterator<_Iterator>& __x,
          const reverse_iterator<_Iterator>& __y)
#else
inline auto
operator-(const reverse_iterator<_Iterator> &__x,
          const reverse_iterator<_Iterator> &__y)
-> decltype(__x.base() - __y.base())
#endif
{ return __y.base() - __x.base(); }

for循环

2.0新增新语法本质是将后边的集合取出来依次赋值给前面申明的变量。

#include <iostream>
#include <vector>

using namespace std;



int main() 
{
	vector<int> Vec{1,2,3,4,5,6,7,8,9,10};

	for (auto value:Vec) 
	{
		cout << value << "  ";
	}

	cout << endl;


	for (auto& value : Vec)
	{
		value *= 5;
	}


	for (auto p = Vec.begin(),end = Vec.end(); p != end; ++p) 
	{
		cout << *p << "  ";
	}

	cout << endl;


	return 0;
}

输出结果:

注意:

  • 上图中申明引用类型的速度快很多,因为引用相当于指针的操作只操作4个字节,而非引用的速度开销随着数据类型所占空间增长而增大,且声明引用后的修改将直接影响到集合中数据的值;
  • 用for操作容器时,标准库规定,关联容器都不允许通过迭代器修改修改容器的值,也就是说上面申明为引用的for循环无法修改关联容器里的数值(因为关联容器的迭代器是const);
  • 当解引用一个关联容器迭代器时,会获得一个类型为value_type的值的引用。对于map而言,value_type是一个pair,pair由first和second组成,first成员保存const关键字,second保存值,而对于set而言,set的迭代器也是const,虽然set定义了iterator和const_iterator类型,但是两种类型都只允许只读set的元素;
  • 因为set使用红黑树做底部结构,但是set只有一个元素(key和data是一样得,也就是说key就是value),所以set是不允许改变元素值得,所以在实现上,set的迭代器拿到的是const的iterator,是不能修改的;
  • 我们通常不去对关联容器使用泛型算法,因为set的关键字是const的,而map的元素pair的第一个成员也是const的,因此不能将关联容器传递给修改或重排元素的算法(实际中我们使用泛型算法一般只把关联容器当成我们要操作数据的源头位置或者目的位置,例如copy算法将元素从一个关联容器拷贝到另一个序列)。

decltype

C++没有typeof关键字;您必须查看一些编译器特定的扩展,如果正在讨论GCC的typeof,那么类似的功能通过关键字decltype存在于C++ 11中。

  • typeid这是在C++头文件typeinfo定义type_info的文件中被提及。

  • typeof在C的GCC扩展和C++ Boost库中定义。

typeid是一个C++语言运算符,它在运行时返回类型标识信息。它基本上返回一个type_info对象,它与其他type_info对象相等,注意:唯一的定义的返回type_info对象的属性有是其正equality-和不相等可比的,即type_info描述不同类型的应比较不相等的,而type_info对象描述相同类型的对象必须比较相等。其他一切都是实现定义的。返回各种“名称”的方法不保证能够返回任何可读的内容,甚至不能保证返回任何内容;上述可能暗示(尽管标准似乎没有明确提及它),typeid对同一类型的连续应用可能会返回不同的对象(当然,这仍然需要进行比较等于)。

#include <iostream>
#include <vector>
#include <set>
using namespace std;

class Person {
public:
	string firstname;
	string lastname;
};

template<typename T1, typename T2>
auto add(T1 x, T2 y) -> decltype(x + y) {
	return x + y;
}


int main() 
{

	// 1.used to declare return tyoes
	cout << add(1, 2) << endl;

	//2. 获取容器的value_type
	std::vector<int> testVec;

	decltype(testVec)::value_type type;// int type;
	decltype(testVec) Vec;//std::vector<int> Vec;

	Vec.insert(Vec.begin(), 99);
	type = 199;

	cout << "type=" << type << "Vec[0]=" << Vec[0] << endl;

	
	// 3. 获取lambda所表示的类型
	auto cmp = [](const Person &p1, const Person &p2) {
		return p1.lastname< p2.lastname;
	};
	set<Person, decltype(cmp)> col(cmp);

	return 0;
}

nullptr

nullptr 是个新关键字,它被自动转换为各种 pointer 类型,但不会被转换为任何整数类型;其类型为std::nullptr_t,定义于 <cstddef>。

void f(int i) 
{
	cout << "f(int)" << endl;
}

void f(void*) 
{
	cout << "f(void*)" << endl;
}

int main() 
{
	f(0);
	f(NULL);
	f(nullptr);

	return 0;
}

输出结果:

 

 

以上参考:

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值