[C++]——C++11 の新機能の簡単な紹介

序文:

  • 今回からC++11の新しい知識を学んでいきます!早速、今日の学習を直接始めましょう。

目次

(1) C++11入門

(2) 統合リストの初期化

1. {} の初期化

2、std::initializer_list

(3) 声明

1、自動

2、decltype

3、nullptr

(4) ループの範囲

(5) STL の一部変更

要約する


(1) C++11入門

2003 年に C++ 標準委員会は技術修正案 (略して TC1) を提出し、C++98 が C++11 と呼ばれる前の最新の C++ 標準の名前は C++03 に置き換えられました。ただし、C++03 (TC1) は主に C++98 標準の抜け穴を修正しており、言語のコア部分は変更されていないため、人々は習慣的に 2 つの標準を組み合わせて C++98/03 と呼んでいます。標準です。C++0x から C++11 まで、C++ 標準は 10 年間にわたって研削されてきましたが、2 番目の真の標準は遅れて登場しました。C++98/03 と比較して それに比べて、C++11 はシステム開発やライブラリ開発に適しており、構文がより一般的で簡素化されており、安定性と安全性が高く、より強力であるだけでなく、プログラマの開発効率も向上します。 . 企業の実際のプロジェクト開発でもよく使われるので、重点的に勉強しておきましょう。C++11 で追加された文法機能は非常に長く、ここで一つ一つ説明することはできませんので、このコースでは実践でより実践的な文法を中心に説明します。

[知識の拡大]
1998 年は C++ 標準委員会が設立された初年度であり、当初は実際のニーズに基づいて 5 年ごとに標準を更新する予定でしたが、C++ 国際標準委員会が次期バージョンの C++03 を検討していたとき、当初の計画は 2007 年リリースだったので、この標準は当初 C++07 と呼ばれていました。しかし、2006 年までに関係者は、C++07 は 2007 年には絶対に完成しない、また 2008 年には完成しないかもしれないと感じていました。最終的には、単に C++ 0x と呼ばれるようになりました。× は、2007 年、2008 年、または 2009 年に完成するかどうかわからないことを意味します。その結果、2010 年には完成せず、C++ 標準がようやく完成したのは 2011 年でした。そこで最終的には C++11 と名付けられました。


(2) 統合リストの初期化

次に、C++11 の最初の新機能である統合リストの初期化に関する知識を正式に学習し始めます。

1. {} の初期化

中括弧 {} を使用した初期化は、さまざまな場合でも一貫した動作を提供し、いくつかの特別な初期化ルールとセマンティクスを持ちます。

C++11 における中括弧を使用した初期化の例をいくつか示します。

  • 直接初期化:
int main()
{
	int x{ 42 }; // 使用大括号直接初始化 x 为 42
	string str{ "Hello" }; // 使用大括号直接初始化字符串对象

	cout << x << endl;
	cout << str << endl;
	return 0;
}

出力表示:

 

  • デフォルトの初期化:
int main()
{
	int x{}; // 使用大括号进行默认初始化,x 的值为 0
	string str{}; // 使用大括号进行默认初始化,str 为空字符串

	cout << x << endl;
	cout << str << endl;
	return 0;
}

出力表示:

  •  配列または構造体の初期化

C++98 では、標準により、配列または構造要素の均一なリスト初期化に中かっこ {} の使用が許可されています。例えば:
 

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 では、中括弧で囲まれたリスト (初期化リスト) の使用範囲が拡張され、すべての組み込み型およびユーザー定義型で使用できるようになりました。等号 (= )、または追加されません

コード表示:

int main()
{
	int x1 = 1;
	int x2{ 2 };

	cout << x1 << endl;
	cout << x2 << endl;
	return 0;
}

出力表示:

 したがって、上記の構造体と配列の初期化操作は、C++11 では次のように変換できます。

struct Point
{
	int _x;
	int _y;
};
int main()
{
	//c++98
	/*int array1[] = { 1, 2, 3, 4, 5 };
	int array2[5] = { 0 };
	Point p = { 1, 2 };*/

	//c++11
	int array1[]{ 1, 2, 3, 4, 5 };
	int array2[5]{ 0 };
	Point p{ 1, 2 };

	return 0;
}

出力表示: 

 

  •  オブジェクトを作成するときに、リスト初期化メソッドを使用してコンストラクターの初期化を呼び出すこともできます。
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()
{
	// old style
	Date d1(2022, 1, 1); 
	
	// C++11支持的列表初始化,这里会调用构造函数初始化
	Date d2{ 2022, 1, 2 };
	Date d3 = { 2022, 1, 3 };
	
	return 0;
}

出力表示:

 【説明する】

  • ここでの本質は、最適化後の構築 + コピー構築です。コンパイラに最適化設定を実行させたくない場合は、明示的に追加できます。

 【まとめ】

  1. 多くの状況において、中括弧の初期化を使用することは、従来の代入や中括弧の初期化よりも安全で柔軟です。
  2. これを使用すると、縮小変換の問題を解決し、統一された初期化構文を提供し、より厳密な型チェックを実行できます。

2、std::initializer_list

std::initializer_list は、C++11 で導入された標準ライブラリ型で、初期化リストを簡単に表すために使用されます。同じ型の値のセットを格納するために使用される軽量のコンテナ クラスです。

std::initializer_listを使用して、一連の値を引数として関数またはコンストラクターに渡したり、オブジェクトの初期化に渡します。その構文は中括弧の初期化に似ています が、より柔軟な渡し方と使用方法を提供します。 {}

std::initializer_listの一般的な使用法をいくつか示します 。

  • パラメータとして関数に渡される
void Point(initializer_list<int> values) {
    for (const auto& value : values) {
        cout << value << " ";
    }
    cout << endl;
}

int main() {
    Point({ 1, 2, 3, 4 }); // 使用初始化列表作为参数
    return 0;
}

出力表示:

 


  • オブジェクトのコンストラクターパラメータとして
class MyClass {
public:
    MyClass(initializer_list<int> values) {
        // 在构造函数中使用初始化列表
        for (const auto& value : values) {
            // 处理每个值
            cout << value << " ";
        }
    }
};

int main() 
{
    MyClass obj({ 1, 2, 3, 4 }); // 使用初始化列表作为构造函数参数
    return 0;
}

出力表示:

 


  • 範囲ベースのループで使用されます
int main()
{
	initializer_list<int> values = { 1, 2, 3, 4 };
	for (const auto& value : values) {
		// 处理每个值
		cout << value << " ";
	}
	return 0;
}

出力表示:

 


std::initializer_listの主な利点は、初期化リストを渡すための簡潔かつ直感的な方法を提供することです。これは、パラメーターの数が未定の関数またはコンストラクターに特に適しています。標準コンテナと同様の方法で、その内部の値へのトラバースとアクセスが可能になります。

 これは、C++11 では、vector が次のコンストラクターを提供するためです。

 


: std::initializer_list は 読み取り専用のコンテナーであり、要素の挿入、削除、変更はできませんその要素タイプは定数であるため、通常は const auto& 要素を反復するために使用されます。

1. エラーレポートを挿入する

 

2. エラーレポートを削除する

 

3. エラーレポートを修正する

 

【まとめ】

  • つまり、std::initializer_list は初期化リストを処理するための簡潔で便利な方法を提供し、C++11 以降のバージョンで広く使用されています。
  • これにより、より直感的でタイプセーフな方法で初期化リストを処理できるようになり、関数やコンストラクターへのパラメーターの受け渡しが簡素化されます。

(3) 声明

C++11 では、特にテンプレートを使用する場合に、宣言を簡素化するさまざまな方法が提供されています。
 

1、自動

C++98 では、auto はストレージ型指定子であり、変数がローカルの自動ストレージ型であることを示しますが、ローカル ドメインで定義されたローカル変数はデフォルトで自動ストレージ型になるため、auto には値がありません。C++11 では、auto の本来の使用法は破棄され、自動型推論を実現するために使用されます。これには明示的な初期化が必要です。これにより、コンパイラは定義オブジェクトの型を初期化値の型に設定します

以下にいくつかの auto 使用例を示します。

  • 自動型推論
int main()
{
	auto num = 42; // 推断 num 的类型为 int

	auto str = "Hello"; // 推断 str 的类型为 const char*

	auto arr = std::vector<int>(); // 推断 vec 的类型为 std::vector<int>

	return 0;
}

出力表示:

 これらの例では、auto キーワードは初期化式に基づいて変数の型を推測し、それに応じて変数を宣言します。


  • 範囲ベースのループと組み合わせる(これは常に使用しているため、多くは言いません)

 

  • 関数の戻り値の型の推論
auto add(int a, int b) {
    return a + b;
}

この例では、auto 関数の戻り値の型を推論するために使用されます。戻り値の式の型に基づいて、コンパイラは関数の戻り値の型を自動的に推測します。


【まとめ】

  1. auto 推論された型は、実行時ではなくコンパイル時に決定されます。auto これは、変数を使用して宣言された変数は、コンパイル時に初期化子式の型に基づいて型が推論され、後続のコードでは決定された型を持つものとして扱われることを意味します。 
  2. また、 auto 初期化式に基づいて型を推論するため、場合によっては予期しない型推論結果や曖昧な型が発生する可能性があります。このような場合、明示的な型宣言またはその他のより具体的な型推論ツール (型変換演算子など) を使用して曖昧さを解消できます。

2、decltype

キーワードdecltype は、変数が式で指定された型であることを宣言します。

コード例:

int main()
{
	const int x = 1;
	double y = 2.2;

	decltype(x * y) ret; // ret的类型是double
	decltype(&x) p; // p的类型是 const int*

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


	return 0;
}

出力表示:

 


3、nullptr

C++ では NULL はリテラル 0 として定義されており、0 はポインター定数と整数定数の両方を表すことができるため、問題が発生する可能性があります
そのため、明確さと安全性の観点から、C++11 では null ポインターを表すために nullptr が追加されています。
 

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

(4) ループの範囲

これについては前のコースですでに詳しく説明したので、ここでは説明しません。


(5) STL の一部変更

新しいコンテナー
オレンジ色の丸で囲まれたものは C++11 のいくつかの新しいコンテナーですが、実際に最も便利なものは unowned_map と
unowned_set です。これら 2 つについては以前に詳しく説明しましたが、他のものについては学ぶだけで大丈夫です。
 

 


要約する

以上が今回のC++11の新機能の紹介です。上記の内容は学校採用ではおなじみの内容なので、知っておくだけで活用できます!

 

おすすめ

転載: blog.csdn.net/m0_56069910/article/details/132460924