[C++11] Introduction to the new features of C++11

Table of contents

1. Introduction to C++11

2. Uniform list initialization

2.1 {} initialization

2.2 std::initializer_list

3. Statement

3.1 auto

3.2 decltype

3.3 nullptr

4. Range for loop

Five, some changes in STL in C++11


1. Introduction to C++11

  • In 2003, the C++ Standards Committee submitted a Technical Corrigendum (TC1 for short), so that the name C++03 has replaced the name of the latest C++ standard before C++98 was called C++11. However, since C++03 (TC1) mainly repairs the loopholes in the C++98 standard, the core part of the language has not been changed, so people habitually call the combination of the two standards the C++98/03 standard .
  • From C++0x to C++11, the C++ standard has been sharpened for 10 years, and the second real standard Shanshan is late. Compared with C++98/03, C++11 has brought a considerable number of changes, including about 140 new features, and about 600 bug fixes in the C++03 standard, which makes C ++11 is more like a new language conceived from C++98/03.
  • In comparison, C++11 can be better used for system development and library development, the syntax is more generalized and simplified, more stable and safer, not only has more powerful functions, but also can improve the development efficiency of programmers. It is also used a lot in project development, so we have to learn it as a key point.

The grammatical features added by C++11 are very long, and the article only explains the commonly used grammar

If you want to check other syntax features of C++11, you can go to the official website for inquiries: C++11 - cppreference.com icon-default.png?t=N2N8https://en.cppreference.com/w/cpp/11  Short story:

  • 1998 was the first year of the establishment of the C++ Standards Committee. It was originally planned to update the standard every five years depending on actual needs. When the C++ International Standards Committee was studying the next version of C++03, it was originally planned to be released in 2007. So initially the standard was called C++07. But by 2006, the official felt that C++07 would definitely not be completed in 2007, and the official felt that it might not be completed in 2008. In the end, it was simply called C++0x. x means that I don't know whether it can be completed in 2007, 2008 or 2009. As a result, it was not completed in 2010, and finally the C++ standard was finally completed in 2011. So it was finally named C++11

The syntax commonly used in C++11 is as follows: list initialization, variable type deduction, range for loop, final and override, smart pointer, some changes of STL, default member function control, rvalue reference, lambda expression, wrapper , thread library , etc.

2. Uniform list initialization

2.1 {} initialization

In C++98, the standard allows the use of curly braces {} for uniform list initialization of array or structure elements

For example:

struct Point
{
	int _x;
	int _y;
};
int main()
{
	//使用 {} 对数组初始化
	int array1[] = { 1, 2, 3, 4, 5 };
	int array2[5] = { 0 };
	//使用 {} 对结构体元素进行初始化
	Point p = { 1, 2 };
	return 0;
}

C++11 expands the scope of use of the list enclosed in curly braces (initialization list), so that it can be used for all built-in types and user-defined types. When using the initialization list, you can add an equal sign (=), or do not add

test code

//C++11
struct Point
{
	int _x;
	int _y;
};
int main()
{
	int x1 = 1; 
	//支持使用 {} 对内置类型进行初始化
	int x2 = { 2 }; //可以加 =
	int x3{ 3 }; //也可以不加 =

	//支持使用 {} 对数组进行初始化
	int array0[] = { 1, 2, 3, 4, 5, 6 }; //可以加 = ,也可以不加 =
	int array1[]{ 1, 2, 3, 4, 5, 6};
	int array2[5]{ 0 };

	//支持使用 {} 对结构体元素进行初始化
	Point p1{ 1, 2 };
	Point p2 = { 1, 2 };

	// C++11中列表初始化也可以适用于new表达式中(在C++98无法初始化)
	int* pa1 = new int[4]{ 0 }; //可以加 = ,也可以不加 =
	int* pa2 = new int[4]{ 1,2,3,4 };  //可以加 = ,也可以不加 =
	return 0;
}

 When creating an object, you can also use the list initialization method to call the constructor initialization

test code

class Date
{
public:
	Date(int year, int month, int day)
		:_year(year)
		, _month(month)
		, _day(day)
	{
		cout << "Date(int year, int month, int day)" << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Date d1(2022, 1, 1); //一般初始化方式

	// C++11支持的列表初始化,这里会调用构造函数初始化
	Date d2{ 2022, 1, 2 };
	Date d3 = { 2022, 1, 3 };
	return 0;
}

 operation result

2.2 std::initializer_list

The initializer_list container has been added to C++11, and the introduction document of std::initializer_list:

initializer_list - C++ Reference (cplusplus.com)icon-default.png?t=N2N8https://legacy.cplusplus.com/reference/initializer_list/initializer_list/

The container does not provide too many member functions

The initializer_list is essentially a list enclosed by {}. If you use the auto keyword to define a variable to receive a list enclosed in braces, check the type of the variable, and you will find that the type of the variable is initializer_list 

int main()
{
	// the type of il is an initializer_list
	auto il = { 10, 20, 30 };
	//typeid(il).name 获取 il 的类型
	cout << typeid(il).name() << endl;
	return 0;
}

Note: typeid(variable name).name can be used to get the type of variable

operation result

 

std::initializer_list usage scenario:
std::initializer_list is generally used as a parameter of the constructor. C++11 adds std::initializer_list as a parameter constructor for many containers in STL, so that it is more convenient to initialize the container object , which allows other containers to support list initialization . It can also be used as a parameter of operator=, so that it can be assigned with curly braces 

Such as list, vector, map and other containers

The list is as follows

Take list as an example, other containers will not take screenshots

test code

int main()
{
	vector<int> v = { 1,2,3,4 };
	list<int> lt = { 1,2 };

	// 这里{"sort", "排序"}会先初始化构造一个pair对象
	map<string, string> dict = { {"sort", "排序"}, {"insert", "插入"} };

	// 支持使用大括号对容器赋值
	v = { 10, 20, 30 };
	return 0;
}

 Note: C++98 does not support the initialization of containers directly with lists. This initialization method is only supported after the introduction of initializer_list in C++11.

3. Statement

c++11 provides various ways to simplify declarations, especially when using templates

3.1 auto

In C++98, auto is a storage type specifier, indicating that the variable is a local automatic storage type, but the local variable defined in the local field is the automatic storage type by default, so auto has no value. The original usage of auto is discarded in C++11, and it is used to realize automatic type leg breaking. This requires explicit initialization, which lets the compiler set the type of the definition object to the type of the initialization value

auto is also often used before, so I won’t introduce too much, the test code:

int main()
{
	int i = 10;
	auto p = &i;
	auto pf = strcpy;

	cout << typeid(p).name() << endl;
	cout << typeid(pf).name() << endl;

	map<string, string> dict = { {"sort", "排序"}, {"insert", "插入"} };
	map<string, string>::iterator it1 = dict.begin();
	auto it2 = dict.begin();// it1 = it2,使用auto简化

	return 0;
}

operation result

3.2 decltype

The keyword  decltype declares the type of the variable as the type specified by the expression

test code

// decltype的一些使用使用场景
template<class T1, class T2>
void F(T1 t1, T2 t2)
{
	decltype(t1 * t2) ret;
	cout << typeid(ret).name() << endl;
}
int main()
{
	const int x = 1;
	double y = 2.2;
	decltype(x * y) ret; // ret的类型是double
	decltype(&x) p; // p的类型是int const *

	cout << typeid(ret).name() << endl;
	cout << typeid(p).name() << endl;
	F(1, 'a');
	return 0;
}

operation result

In addition to being able to deduce the type of an expression, decltype can also deduce the type of a function return value 

void* GetMemory(size_t size)
{
	return malloc(size);
}
int main()
{
	//如果没有带参数,推导函数的类型
	cout << typeid(decltype(GetMemory)).name() << endl;
	//如果带参数列表,推导的是函数返回值的类型,注意:此处只是推演,不会执行函数
	cout << typeid(decltype(GetMemory(1))).name() << endl;
	return 0;
}

operation result

 

3.3 nullptr

Since NULL is defined as a literal 0 in C++, this may cause some problems, because 0 can represent both a pointer constant and an integer constant. So for the sake of clarity and safety, C++11 has added nullptr to represent a null pointer

In the traditional C header file (stddef.h): 

#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif

This has been introduced in Introduction to C++

4. Range for loop

For a ranged collection, it is redundant and sometimes error-prone for the programmer to specify the range of the loop. So range-based for loops were introduced in C++11. The parentheses after the for loop are divided into two parts by the colon ":": the first part is the variable used for iteration in the range, and the second part represents the range to be iterated

void TestFor()
{
    int array[] = { 1, 2, 3, 4, 5 };
    for(auto& e : array)
    e *= 2;
    for(auto e : array)
    cout << e << " ";
 
    return 0;
}

 Note: Similar to ordinary loops, you can use continue to end this loop, or use break to jump out of the entire loop

Conditions for the use of range for:

  1. The range of for loop iterations must be deterministic
  2.  The iterated object must implement ++ and == operations

(1) For an array, it is the range of the first element and the last element in the array; for a class, methods of begin and end should be provided, and begin and end are the range of for loop iterations

(2) Because the bottom layer of range for is implemented by iterators, when the code is compiled, the compiler will automatically replace range for with the form of iterators. And because ++ and == operations need to be performed on objects when traversing with iterators, objects using range for also need to support ++ and == operations

Five, some changes in STL in C++11

New container

Four new containers have been added in C++11, namely array, forward_list, unordered_map and unordered_set

Note: array and forward_list are useless, so you can ignore them. Unordered_map, unordered_set, and array are introduced in the previous chapters, so I won’t explain them here

Some new methods in the container

C++11 adds some new methods to each container, such as:

  • A constructor that takes an initializer_list as an argument is provided to support list initialization.
  • Provides cbegin and cend methods for returning const iterators. But the practical significance is not great, because begin and end can also return const iterators, these are icing on the cake operations
  • Provides the emplace series of methods, and overloads an rvalue reference version of the insertion function based on the original insertion method of the container to improve the efficiency of inserting elements into the container

Note: The emplace series methods involve variable parameters of rvalue references and templates, which will be explained later

----------------I am the dividing line---------------

The article is over here, the next one will be updated soon

Guess you like

Origin blog.csdn.net/m0_64280701/article/details/130112764