はじめに
C++11は「モダンC++」の始まりと呼ばれる大型アップデート。
「まだC++03の書き方してるんだけど...」って人、意外といるんじゃない?
この記事で「C++11を使わない理由はない」という気持ちになれば嬉しい。
1. auto
型推論で変数宣言が簡潔に:
auto x = 42; // int
auto y = 3.14; // double
auto s = string("Hi"); // std::string
// イテレータの型を省略
vector<int> vec = {1, 2, 3};
for (auto it = vec.begin(); it != vec.end(); ++it) {
cout << *it << endl;
}
2. 範囲for文
コンテナの走査が簡単に:
vector<int> vec = {1, 2, 3, 4, 5};
// 値でアクセス
for (int v : vec) {
cout << v << endl;
}
// 参照で変更
for (int& v : vec) {
v *= 2;
}
// const参照(推奨)
for (const auto& v : vec) {
cout << v << endl;
}
3. ラムダ式
無名関数をその場で定義:
// 基本形
auto hello = []() { cout << "Hello!" << endl; };
hello();
// 引数と戻り値
auto add = [](int a, int b) -> int { return a + b; };
cout << add(3, 4); // 7
// キャプチャ
int x = 10;
auto by_val = [x]() { return x; }; // 値キャプチャ
auto by_ref = [&x]() { x++; }; // 参照キャプチャ
auto all_val = [=]() { return x; }; // 全て値
auto all_ref = [&]() { x++; }; // 全て参照
STLと組み合わせ
vector<int> nums = {3, 1, 4, 1, 5};
// ソート(降順)
sort(nums.begin(), nums.end(), [](int a, int b) {
return a > b;
});
4. nullptr
NULLの代わりに:
int* ptr = nullptr;
if (ptr == nullptr) {
// ヌルチェック
}
なぜnullptr?
- 型安全(
NULLは0に展開されることがある) - オーバーロードで明確に区別可能
5. 初期化リスト
// 均一初期化
vector<int> vec = {1, 2, 3, 4, 5};
array<int, 5> arr = {1, 2, 3, 4, 5};
unordered_map<string, int> m = {{"one", 1}, {"two", 2}};
// 構造体
struct Point { int x, y; };
Point p = {10, 20};
6. スマートポインタ
自動メモリ管理:
// unique_ptr(単独所有)
unique_ptr<int> up = make_unique<int>(42);
// shared_ptr(共有所有)
shared_ptr<int> sp1 = make_shared<int>(100);
shared_ptr<int> sp2 = sp1; // 共有
cout << sp1.use_count(); // 2
// weak_ptr(弱参照)
weak_ptr<int> wp = sp1;
if (auto locked = wp.lock()) {
// 有効な間だけ使用
}
7. ムーブセマンティクス
コピーの代わりに「移動」で高速化:
string s = "Hello World";
string s2 = move(s); // ムーブ(コピーより高速)
// sは空になる可能性
// ムーブコンストラクタ
class MyClass {
public:
MyClass(MyClass&& other) noexcept {
// リソースを移動
}
};
8. constexpr
コンパイル時計算:
constexpr int factorial(int n) {
return (n <= 1) ? 1 : n * factorial(n - 1);
}
constexpr int fact5 = factorial(5); // コンパイル時に120
// 配列サイズに使用可能
int arr[factorial(3)]; // int arr[6]
9. 可変長テンプレート
任意の数の引数を受け取る:
template<typename T>
T sum(T t) { return t; }
template<typename T, typename... Args>
T sum(T first, Args... rest) {
return first + sum(rest...);
}
sum(1, 2, 3, 4, 5); // 15
10. tuple
複数の値をまとめる:
tuple<int, string, double> t(1, "Hello", 3.14);
// アクセス
cout << get<0>(t); // 1
cout << get<1>(t); // "Hello"
// アンパック
int a; string b; double c;
tie(a, b, c) = t;
// 作成
auto t2 = make_tuple(100, "World");
11. enum class
型安全な列挙型:
enum class Color { Red, Green, Blue };
Color c = Color::Red;
// 暗黙変換なし(型安全)
// int x = c; // エラー!
int x = static_cast<int>(c); // 明示的変換
12. override / final
class Base {
virtual void foo() {}
virtual void bar() final {} // オーバーライド禁止
};
class Derived : public Base {
void foo() override {} // オーバーライドを明示
// void bar() override {} // エラー!finalなので不可
};
13. static_assert
コンパイル時アサーション:
static_assert(sizeof(int) == 4, "int must be 4 bytes");
static_assert(sizeof(void*) == 8, "64-bit required");
14. std::thread
標準スレッドライブラリ:
#include <thread>
void worker(int id) {
cout << "Thread " << id << endl;
}
thread t1(worker, 1);
thread t2(worker, 2);
t1.join();
t2.join();
15. std::function
呼び出し可能オブジェクトの汎用ラッパー:
#include <functional>
function<int(int, int)> add = [](int a, int b) {
return a + b;
};
cout << add(3, 4); // 7
まとめ
| 機能 | 用途 |
|---|---|
auto |
型推論 |
| 範囲for | コンテナ走査 |
| ラムダ | 無名関数 |
nullptr |
ヌルポインタ |
| スマートポインタ | 自動メモリ管理 |
| ムーブ | 高速なリソース移動 |
constexpr |
コンパイル時計算 |
enum class |
型安全列挙 |
override/final
|
継承制御 |
thread |
マルチスレッド |
C++11は必須知識です。これ以降のC++を理解する基礎になります!