yohhoyの日記

技術的メモをしていきたい日記

構造化束縛 in 条件式 @ C++26

プログラミング言語C++の次期標準C++2c(C++26)から、if/while/for/switch構文の条件式(condition)部に構造化束縛(structured binding)を記述できる。

// C++2c
if (auto [a, b] = func()) {
  // 関数戻り値からbool型への変換結果がtrueとなるときに限り
  // 戻り値オブジェクトから変数a, bへの分割代入が行われる
}
// 下記コード動作と等価
auto r = func();
if (r) {
  auto [a, b] = r;
  // ...
}

またC++2c採択済み提案文書P2497R0により、std::to_charsstd::from_chars関数の各戻り値型std::to_chars_resultstd::from_chars_resultにbool型への変換(→id:yohhoy:20121110)が追加され、構造化束縛による結果取得と変換成功判定ec == errc{}を簡素に記述できるようになる。*1

#include <charconv>

char buf[8];
char* last = buf + sizeof(buf);

// C++17/20/23
if (auto [ptr, ec] = std::to_chars(buf, last, 42); ec == std::errc{}) {
  // ...
}

// C++2c
if (auto [ptr, ec] = std::to_chars(buf, last, 42)) {
  // ...
}

Clang 6.0.0以降は独自拡張として本機能をサポート*2しているが、戻り値オブジェクトの条件評価と分割代入の評価順がC++2c言語機能と異なることに注意。

// Clang独自拡張: 下記コード動作と等価
auto r = func();
if (auto [a, b] = r; r) {
  // ...
}

関連URL

*1:本来はC++23時点で採択予定だったようだが、手続き上の問題でC++2cに遅延したとのこと。https://github.com/cplusplus/papers/issues/1454

*2:https://github.com/llvm/llvm-project/blob/llvmorg-6.0.0/clang/include/clang/Basic/DiagnosticSemaKinds.td#L417-L419