6
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめに

C++20はC++11以来の大型アップデート。Concepts、Ranges、Coroutinesなど革新的な機能が追加された。

特にConceptsは「テンプレートのエラーメッセージが読めない」というC++の古来の問題を解決してくれる。

1. Concepts(コンセプト)

テンプレートの制約を明確に:

#include <concepts>

// 数値型を制約
template<typename T>
concept Numeric = is_arithmetic_v<T>;

template<Numeric T>
T add(T a, T b) {
    return a + b;
}

add(3, 4);       // OK
add(1.5, 2.5);   // OK
// add("a", "b"); // エラー!

// カスタムコンセプト
template<typename T>
concept Printable = requires(T t) {
    { cout << t } -> same_as<ostream&>;
};

2. Ranges

コンテナ操作をパイプラインで:

#include <ranges>

vector<int> nums = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

// フィルタ→変換をパイプで連結
auto result = nums 
    | views::filter([](int n) { return n % 2 == 0; })
    | views::transform([](int n) { return n * n; });
// {4, 16, 36, 64, 100}

// take / drop
auto first3 = nums | views::take(3);     // {1, 2, 3}
auto skip3 = nums | views::drop(3);      // {4, 5, ...}

// reverse
auto rev = nums | views::reverse;

// iota(連続整数生成)
for (int n : views::iota(1, 6)) {        // 1, 2, 3, 4, 5
    cout << n << endl;
}

3. 三方比較演算子 (<=>)

「宇宙船演算子」で比較を一括定義:

struct Point {
    int x, y;
    auto operator<=>(const Point&) const = default;
};

Point p1{1, 2}, p2{1, 3};
p1 == p2;  // false
p1 < p2;   // true
p1 != p2;  // true
// ==, !=, <, <=, >, >= すべて自動生成

4. std::format

Pythonライクな文字列フォーマット:

#include <format>

string name = "World";
format("Hello, {}!", name);           // "Hello, World!"
format("Pi = {:.2f}", 3.14159);       // "Pi = 3.14"
format("{:>10}", "right");            // "     right"
format("{:^10}", "center");           // "  center  "
format("Hex: {:x}", 255);             // "Hex: ff"
format("Bin: {:b}", 255);             // "Bin: 11111111"

5. std::span

配列の軽量ビュー:

#include <span>

void process(span<const int> s) {
    for (int n : s) { /* ... */ }
}

int arr[] = {1, 2, 3, 4, 5};
vector<int> vec = {1, 2, 3};

process(arr);  // 配列
process(vec);  // vector
// どちらも同じ関数で処理可能

// 部分取得
span<int> sp(arr);
sp.subspan(1, 3);  // {2, 3, 4}

6. constexpr の拡張

vectorstringもconstexprで使用可能:

constexpr int sum() {
    vector<int> v = {1, 2, 3, 4, 5};
    int total = 0;
    for (int n : v) total += n;
    return total;
}

constexpr int result = sum();  // 15(コンパイル時)

7. consteval / constinit

// consteval: 必ずコンパイル時評価
consteval int square(int n) {
    return n * n;
}

constexpr int x = square(5);  // OK
// int y = square(runtime_val); // エラー!

// constinit: 静的初期化を強制
constinit int global = 42;

8. 指示付き初期化

C99スタイルの初期化:

struct Config {
    int width = 800;
    int height = 600;
    bool fullscreen = false;
};

Config cfg = {
    .width = 1920,
    .height = 1080,
    .fullscreen = true
};

9. ラムダの拡張

// テンプレートラムダ
auto print = []<typename T>(vector<T> const& vec) {
    for (const auto& v : vec) cout << v;
};

// thisのコピーキャプチャ
struct S {
    int value;
    auto get_lambda() {
        return [*this]() { return value; };
    }
};

10. std::source_location

ファイル名・行番号を自動取得:

#include <source_location>

void log(string_view msg, 
         source_location loc = source_location::current()) {
    cout << loc.file_name() << ":" << loc.line() 
         << " " << msg << endl;
}

log("Error!");  // main.cpp:42 Error!

11. std::numbers

数学定数:

#include <numbers>

numbers::pi;    // 3.14159...
numbers::e;     // 2.71828...
numbers::sqrt2; // 1.41421...
numbers::phi;   // 1.61803... (黄金比)
numbers::ln2;   // 0.69314...

12. std::bit

ビット操作:

#include <bit>

popcount(0b00101100u);     // 3 (1のビット数)
has_single_bit(64u);       // true (2の累乗)
bit_ceil(44u);             // 64 (以上の最小2累乗)
bit_floor(44u);            // 32 (以下の最大2累乗)
countl_zero(0b00101100u);  // 26 (左側のゼロ)
countr_zero(0b00101100u);  // 2 (右側のゼロ)

13. using enum

enum値を直接使用:

enum class Color { Red, Green, Blue };

void func() {
    using enum Color;
    Color c = Red;  // Color::Red の代わり
}

14. contains

map/setの存在確認が簡単に:

set<int> s = {1, 2, 3};
map<string, int> m = {{"one", 1}};

s.contains(2);       // true
m.contains("one");   // true
// count() や find() より直感的

15. starts_with / ends_with

文字列の前方/後方一致:

string s = "Hello World";

s.starts_with("Hello");  // true
s.ends_with("World");    // true

まとめ

機能 説明
Concepts テンプレート制約
Ranges パイプラインコンテナ操作
<=> 三方比較(宇宙船演算子)
format 文字列フォーマット
span 配列ビュー
consteval コンパイル時専用関数
指示付き初期化 .member = value
source_location ログ用ファイル/行情報
numbers 数学定数
bit ビット操作
contains 存在確認
starts_with 前方一致
6
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?