7
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++23はC++20の改善版で、より使いやすい機能が追加されている。

特にstd::printは「やっとか!」って感じ。cout << ... << endlの呼吸からやっと解放される。

※ 一部機能はコンパイラのサポート状況により使用できない場合があるよ。

1. std::print / std::println

coutの代わりに:

#include <print>

int x = 42;
string name = "World";

std::print("Hello, {}!", name);       // 改行なし
std::println("The answer is {}", x);  // 改行あり

// cout より簡潔
// cout << "Hello, " << name << "!" << endl; // 従来

2. deducing this

メンバ関数でthisの型を推論:

struct MyClass {
    // 従来:const/非const版を両方書く必要があった
    // int& get() { return value; }
    // const int& get() const { return value; }
    
    // C++23:1つで両方対応
    template<typename Self>
    auto& get(this Self& self) {
        return self.value;
    }
    
    int value;
};

MyClass obj;
const MyClass cobj;

obj.get() = 10;        // int&
auto v = cobj.get();   // const int&

CRTP の簡略化

// 従来のCRTP
template<typename Derived>
struct Base {
    void interface() {
        static_cast<Derived*>(this)->impl();
    }
};

// C++23
struct Base {
    template<typename Self>
    void interface(this Self& self) {
        self.impl();
    }
};

3. [[assume]] 属性

最適化のヒントを与える:

int divide(int a, int b) {
    [[assume(b != 0)]];  // bは0でないと仮定
    return a / b;        // ゼロ除算チェックを省略できる
}

void process(int* ptr) {
    [[assume(ptr != nullptr)]];
    // nullチェック省略可能
}

4. if consteval

constevalコンテキストかどうかを判定:

constexpr int compute(int n) {
    if consteval {
        // コンパイル時評価
        return n * n;
    } else {
        // 実行時評価
        return some_runtime_function(n);
    }
}

5. std::expected

エラーハンドリングの新しい方法:

#include <expected>

std::expected<int, string> parse_int(string_view s) {
    try {
        return stoi(string(s));
    } catch (...) {
        return unexpected("Parse error");
    }
}

auto result = parse_int("42");
if (result) {
    cout << *result << endl;
} else {
    cout << "Error: " << result.error() << endl;
}

// value_or
cout << result.value_or(-1) << endl;

6. std::mdspan

多次元配列ビュー:

#include <mdspan>

int data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};

// 3x4 の2次元ビュー
std::mdspan m(data, 3, 4);

m[1, 2] = 100;  // 2行3列目にアクセス

for (int i = 0; i < 3; ++i) {
    for (int j = 0; j < 4; ++j) {
        cout << m[i, j] << " ";
    }
    cout << endl;
}

7. std::generator

コルーチンベースのジェネレータ:

#include <generator>

std::generator<int> fibonacci() {
    int a = 0, b = 1;
    while (true) {
        co_yield a;
        int temp = a;
        a = b;
        b = temp + b;
    }
}

for (int n : fibonacci() | views::take(10)) {
    cout << n << " ";  // 0 1 1 2 3 5 8 13 21 34
}

8. ranges の拡張

zip

vector<int> nums = {1, 2, 3};
vector<string> names = {"a", "b", "c"};

for (auto [n, name] : views::zip(nums, names)) {
    cout << n << ": " << name << endl;
}

enumerate

vector<string> items = {"apple", "banana", "cherry"};

for (auto [i, item] : views::enumerate(items)) {
    cout << i << ": " << item << endl;
}
// 0: apple
// 1: banana
// 2: cherry

chunk / slide

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

// chunk: グループに分割
for (auto chunk : nums | views::chunk(2)) {
    // {1, 2}, {3, 4}, {5, 6}
}

// slide: スライディングウィンドウ
for (auto window : nums | views::slide(3)) {
    // {1, 2, 3}, {2, 3, 4}, {3, 4, 5}, {4, 5, 6}
}

9. std::stacktrace

スタックトレースを取得:

#include <stacktrace>

void foo() {
    auto trace = std::stacktrace::current();
    cout << trace << endl;
}

10. string の resize_and_overwrite

効率的な文字列操作:

string s;
s.resize_and_overwrite(100, [](char* buf, size_t n) {
    // bufに直接書き込み
    strcpy(buf, "Hello");
    return 5;  // 実際の長さを返す
});

11. to_underlying

enumの基底型へ変換:

enum class Color : int { Red = 1, Green = 2, Blue = 3 };

auto val = std::to_underlying(Color::Red);  // 1
// static_cast<int>(Color::Red) より簡潔

12. std::unreachable

到達不能を明示:

int foo(int x) {
    switch (x) {
        case 1: return 10;
        case 2: return 20;
        default:
            std::unreachable();  // ここには到達しない
    }
}

13. constexpr の更なる拡張

// unique_ptr が constexpr で使用可能
constexpr auto make_value() {
    auto p = make_unique<int>(42);
    return *p;
}

constexpr int val = make_value();

14. std::byteswap

エンディアン変換:

#include <bit>

uint32_t x = 0x12345678;
uint32_t y = std::byteswap(x);  // 0x78563412

コンパイラサポート状況

機能 GCC Clang MSVC
print 14+ 17+ 部分的
deducing this 14+ 18+ 19.32+
expected 12+ 16+ 19.33+
mdspan 14+ 17+ 部分的
ranges拡張 14+ 17+ 部分的

まとめ

機能 説明
print/println 簡潔な出力
deducing this thisの型推論
[[assume]] 最適化ヒント
expected エラーハンドリング
mdspan 多次元配列ビュー
generator コルーチンジェネレータ
zip/enumerate ranges拡張
stacktrace スタックトレース取得
unreachable 到達不能マーク
7
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
7
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?