文書の一覧
全部で36本あります(SG22のWG14からのものは除きます)。
- P0429R8 A Standard flat_map
- P0957R7 Proxy: A Polymorphic Programming Library
- P1061R2 Structured Bindings can introduce a Pack
- P1169R4 static operator()
- P1222R3 A Standard flat_set
- P1223R4 find_last
- P1467R9 Extended floating-point types and standard names
- P1642R8 Freestanding Library: Easy [utilities], [ranges], and [iterators]
- P1673R7 A free function linear algebra interface based on the BLAS
- P1674R1 Evolving a Standard C++ Linear Algebra Library from the BLAS
- P1684R2 mdarray: An Owning Multidimensional Array Analog of mdspan
- P1967R5 #embed - a simple, scannable preprocessor-based resource acquisition method
- P2071R2 Named universal character escapes
- P2093R14 Formatted output
- P2174R1 Compound Literals
- P2198R5 Freestanding Feature-Test Macros and Implementation-Defined Extensions
- P2266R3 Simpler implicit move
- P2278R3 cbegin should always return a constant iterator
- P2280R4 Using unknown references in constant expressions
- P2286R7 Formatting Ranges
- P2300R5 std::execution
- P2302R4 std::ranges::contains
- P2322R6 ranges::fold
- P2400R3 Library Evolution Report: 2021-09-28 to 2022-01-25
- P2408R5 Ranges iterators as inputs to non-Ranges algorithms
- P2472R2 make function_ref more functional
- P2505R2 Monadic Functions for std::expected
- P2510R2 Formatting pointers
- P2538R1 ADL-proof std::projected
- P2539R1 Should the output of std::print to a terminal be synchronized with the underlying stream?
- P2542R1 views::concat
- P2546R1 Debugging Support
- P2559R0 Plan for Concurrency Technical Specification Version 2
- P2573R0 = delete("should have a reason");
- P2574R0 2022-05 Library Evolution Polls
- P2577R0 C++ Modules Discovery in Prebuilt Library Releases
- おわり
P0429R8 A Standard flat_map
キーの検索をstd::map
比で高速に行える連想コンテナ、flat_map
の提案。
std::map
はノードベースの連想コンテナであり、個々の要素はノードと呼ばれる単位(key-valueペア及びアロケータ、親と子ノードへのポインタなどをまとめて格納しているもの)でメモリ上に存在しており、多くの場合はノード同士はメモリ上で連続せずに分散して存在しています。そのため、キャッシュ局所性が悪く、キーの検索(ノードの引き当て)のパフォーマンスが悪いことが問題となっていました。
flat_map
の基礎的なアイデアは、シーケンスコンテナ(std::vector
などメモリ連続なコンテナ)上に二分木を構成して使用することで、各要素をメモリ上で連続させてキャッシュ局所性を向上させようとするものです。要は、更新時もソート済みであることが保証されるソート済std::vector
です。したがって、要素の更新はO(N)
(ほぼ常に再配置が発生)、要素の検索はO(logN)
(ソート済み配列上での二分探索)の計算量となります。
この提案のflat_map
ではさらに、キーと値をそれぞれ別のシーケンスコンテナ(デフォルトはstd::vector
)に保持することでキーのキャッシュ局所性をさらに向上させ、検索のパフォーマンス向上の最大化を図っています。そして、この提案のflat_map
はコンテナではなくコンテナアダプタとなり、イテレータはランダムアクセスイテレータ(ただし、C++17以前に対しては入力イテレータ)となります。
namespace std { // std::flat_mapの宣言例 template <class Key, class T, class Compare = less<Key>, class KeyContainer = vector<Key>, class MappedContainer = vector<T>> class flat_map { ... struct containers { KeyContainer keys; MappedContainer values; }; ... private: containers c; // exposition only }; }
また、flat_map
はstd::map
とのインターフェース互換を意識しているため、ほぼ同じインターフェースによって使用可能となっています。
flat_map
はその構造上、要素の挿入(insert()
)や削除(remove()
)が遅く検索(find/operator[]
)及びイテレートが早い連想コンテナです。従って、適した用途は要素の更新よりも参照回数の方が多くなる場合であり、最大のパフォーマンスメリットを得るには最初に一度構築した後は検索しかしないような使い方をする必要があります。
また、flat_map
はノードベースコンテナではないため要素ごとにアロケータや親子ポインタなどを保持する必要がなく、std::map
に比べて要素あたりの空間コストを削減することができます。そのため、パフォーマンスメリットが得られない場合でも省メモリ目的で使用することもできます。
flat_map
はC++20に向けて議論されていましたが、キーと値のコンテナを別々に持つことからそのイテレータのためにzip_view
が必要とされ、zip_view
はその値型(std::pair<T&, U&>/std::tuple<Ts&...>
)のcommon_reference
の問題(std::pair<T&, U&>
<->std::pair<T, U>
のような変換ができない)やswap
の問題(参照pair/tuple
をconst
-assignableにすると正しくswap
されない)の解決のためにC++23に延期されたたため、flat_map
もそれを待たねばなりませんでした。今のところ、C++23に向けてレビューされています(現在LWGでレビュー中)。
- P0429R1 A Standard flat_map
- P0429R2 A Standard flat_map
- 平らな地図、もといflat_map - にゃははー
- P2321R2 zip
- P2569 進行状況
P0957R7 Proxy: A Polymorphic Programming Library
静的な多態的プログラミングのためのユーティリティ、"Proxy"の提案。
以前の記事を参照
- P0957R5 Proxy: A Polymorphic Programming Library - WG21月次提案文書を眺める(2022年02月)
- P0957R6 Proxy: A Polymorphic Programming Library - WG21月次提案文書を眺める(2022年03月)
このリビジョンでの変更は、
proxy::type(), proxy::cast()
をproxy::reflect()
で置き換えた(静的リフレクションを意識して?)bad_proxy_cast
を削除proxy::operator=
の例外指定を変更BasicFacade
(名前付き要件)の指定を変更
などです。
P1061R2 Structured Bindings can introduce a Pack
構造化束縛可能なオブジェクトをパラメータパックに変換可能にする提案。
std::tuple
とパラメータパックは任意の異なるオブジェクトのシーケンスという点でよく似ています。現在、パラメータパックからstd::tuple
へ変換することは簡単にできますが、その逆(std::tuple
->パラメータパック)は少し面倒です。
template<typename... Ts> void pack_to_tuple(Ts&&... ts) { std::tuple<Ts...> t(std::forward<Ts>(ts)...); } template<typename... Ts> void tuple_to_pack(std::tuple<Ts...> t) { std::apply([](auto&&... elems) { // ここでtupleから変換したパックが得られる }, t); }
これは単一のパックの単純な使用においてはそこまで複雑ではありませんが、特定のオーバーロードを解決したいとか、それによって戻り値を返したいとか、複数のtuple
を扱いたいなどしてくると、急速に複雑化します。たとえば、2つのtuple
の内積を求めるようなコードの場合
// std::applyを使用した例 template <class P, class Q> auto dot_product_apply(P p, Q q) { return std::apply([&](auto... p_elems){ return std::apply([&](auto... q_elems){ return (... + (p_elems * q_elems)); }, q) }, p); } // std::index_sequenceを使用した例 template <size_t... Is, class P, class Q> auto dot_product_idxseq(std::index_sequence<Is...>, P p, Q, q) { return (... + (std::get<Is>(p) * std::get<Is>(q))); } template <class P, class Q> auto dot_product_idxseq(P p, Q q) { return dot_product_idxseq( std::make_index_sequence<std::tuple_size<P>::value>{}, p, q); }
どちらもコード自体の短さとは裏腹に、恐ろしいほどの複雑さが詰め込まれています(慣れてるとそう見えなくなってしまうのですが・・・)。そして、このコードはstd::tuple
(あるいは互換インターフェースを備えた型)のみに制限されています。構造化束縛宣言で使用可能なタプルっぽく思える型をここに入れることはできません。
この提案はこれらの複雑さと非一貫性を取り払うために、構造化束縛宣言を拡張してパック導入ができるようにしようとするものです。これによって、std::tuple
からパラメータパックへの変換が簡単になるとともに、それをタプルlikeな任意の型へと拡張することができます。
std::tuple<X, Y, Z> f(); auto [x,y,z] = f(); // OK today auto [...xs] = f(); // proposed: xsは長さ3のパック、X,Y,Zのオブジェクトを含んでいる auto [x, ...rest] = f(); // proposed: xはXのオブジェクト、restは長さ2のパック(Y,Z) auto [x,y,z, ...rest] = f(); // proposed: restは空のパック auto [x, ...rest, z] = f(); // proposed: xはXのオブジェクト、restは長さ1のパック(Y)、zはZのオブジェクト auto [...a, ...b] = f(); // ill-formed: 複数パックへの展開は決定不可能
サンプルコード
std::apply
の実装
現在 | この提案 |
---|---|
namespace detail { template <class F, class Tuple, std::size_t... I> constexpr decltype(auto) apply_impl(F &&f, Tuple &&t, std::index_sequence<I...>) { return std::invoke(std::forward<F>(f), std::get<I>(std::forward<Tuple>(t))...); } } template <class F, class Tuple> constexpr decltype(auto) apply(F &&f, Tuple &&t) { return detail::apply_impl( std::forward<F>(f), std::forward<Tuple>(t), std::make_index_sequence<std::tuple_size_v< std::decay_t<Tuple>>>{}); } |
template <class F, class Tuple> constexpr decltype(auto) apply(F &&f, Tuple &&t) { auto&& [...elems] = t; return std::invoke(std::forward<F>(f), forward_like<Tuple, decltype(elems)>(elems)...); } |
std::apply
を使用した2つのタプルの内積
現在 | この提案 |
---|---|
template <class P, class Q> auto dot_product(P p, Q q) { return std::apply([&](auto... p_elems){ return std::apply([&](auto... q_elems){ return (... + (p_elems * q_elems)); }, q) }, p); } |
template <class P, class Q> auto dot_product(P p, Q q) { // no indirection! auto&& [...p_elems] = p; auto&& [...q_elems] = q; return (... + (p_elems * q_elems)); } |
std::index_sequence
を使用した2つのタプルの内積(std::index_sequence
にタプルインターフェースを追加したとする)
現在 | この提案 |
---|---|
template <size_t... Is, class P, class Q> auto dot_product(std::index_sequence<Is...>, P p, Q, q) { return (... + (std::get<Is>(p) * std::get<Is>(q))); } template <class P, class Q> auto dot_product(P p, Q q) { return dot_product( std::make_index_sequence<std::tuple_size_v<P>>{}, p, q); } |
template <class P, class Q> auto dot_product(P p, Q q) { // no helper function necessary! auto [...Is] = std::make_index_sequence< std::tuple_size_v<P>>{}; return (... + (std::get<Is>(p) * std::get<Is>(q))); } |
この拡張による実装は簡潔であるだけでなく、これらのタプルに限定されていたコードを構造化束縛で利用可能な型に拡張します。たとえば、上記のstd::apply
実装ならば、ユーザー定義型で利用可能となります。
struct Point { int x, y, z; }; Point getPoint(); double calc(int, int, int); double result = std::apply(calc, getPoint()); // 現在はng、この提案による実装ではok
ただし、これを実装すると。非テンプレートコンテキストにおいてもパラメータパックの出現を考慮しなければならなくなるため、実装の複雑さと通常コードへのコンパイル時間の増大等の影響が予想されます。
// 非テンプレートでのパック導入 auto sum_non_template(SomeConreteType tuple) { auto [...elems] = tuple; return (... + elems); }
この提案では、この提案以外の提案(主にリフレクション関係)によって任意の場所にパックを導入するものがいくつかあるということと、この提案によるパックは構造化束縛宣言によってのみ導入され、展開される前に必ず宣言されていることから任意の場所で突然パック展開が出現することはない(ためにすべてのコンテキストでパック展開出現を考慮する必要が無い)、等の事から実装と他コードへの影響は大きくないとしています。
P1169R4 static operator()
関数呼び出し演算子(operator()
)を、静的メンバ関数として定義できるようにする提案。
以前の記事を参照
- P1169R1
static operator()
- [C++]WG21月次提案文書を眺める(2021年04月) - P1169R2
static operator()
- [C++]WG21月次提案文書を眺める(2021年08月) - P1169R3
static operator()
- [C++]WG21月次提案文書を眺める(2021年10月)
このリビジョンでの変更は、提案する文言の調整のみのようです。
この提案はCWGのレビューを終えていますが、ライブラリ部分についてLEWGでの投票待ちをしています。
P1222R3 A Standard flat_set
キーの検索がstd::set
比で高速に行える連想コンテナ、flat_set
の提案。
この提案のモチベーションやメリット、及び設計はほとんど先ほどのflat_map
と共通しています。flat_set
はほぼ、常にソート済みであることが保証されるソート済みvector
であり、要素はメモリ上で連続して配置されています。それによって、検索やイテレート時のキャッシュ局所性が向上しそれらの操作を高速に行うことができ、ノードベースではないことから空間コストも削減することができます。
flat_map
の実装がキーと値のコンテナを別々に持つなど複雑だったのに対して、flat_set
の場合はキーのコンテナ1本のラッパとなるのでかなり単純になります。flat_set
はflat_map
同様にコンテナアダプタであり、そのイテレータはプロクシイテレータかつC++20イテレータとしてはランダムアクセスイテレータとなります(C++17イテレータとしては入力イテレータ)。
namespace std { // flat_setの宣言例 template<class Key, class Compare = less<Key>, class Container = vector<Key>> class flat_set { private: container_type c; // exposition only }; }
この提案はおそらくflat_map
と足並みを揃えるために遅れており、現在はC++23に向けてLWGでレビュー中です。
P1223R4 find_last
指定された値をシーケンスの後ろから探索するfind_last
アルゴリズムの提案。
このリビジョンの変更はfind_last
ファミリの戻り値としてsubrange
を返すようにしたことと、それに伴う提案全体の書き直しなどです。
以前の提案のfind_last
の戻り値は見つけた位置を指すイテレータのみでしたが、この提案では範囲の終端を指すイテレータを含めたsubrange
を返すように変更されました。これはLWGのレビューによるもので、そのAPIの変更の確認のためにSG9およびLEWGでレビューと投票を行っており、現在LEWGでの投票待ちです。
P1467R9 Extended floating-point types and standard names
C++コア言語/標準ライブラリに拡張浮動小数点型のサポートを追加する提案。
以前の記事を参照
- P1467R4 : Extended floating-point types and standard names - [C++]WG21月次提案文書を眺める(2020年06月)
- P1467R7 : Extended floating-point types and standard names - [C++]WG21月次提案文書を眺める(2021年11月)
- P1467R8 : Extended floating-point types and standard names - [C++]WG21月次提案文書を眺める(2021年12月)
このリビジョンでの変更は、LWGのレビューを受けての文言の修正です。
この提案は、このリビジョンでもってCWG/LWGのレビューを終え、C++23に向けて次の全体会議で投票にかけられる予定です。
P1642R8 Freestanding Library: Easy [utilities], [ranges], and [iterators]
[utility]、<ranges>
、<iterator>
から一部のものをフリースタンディングライブラリに追加する提案。
前回の記事を参照
- P1642R3 Freestanding Library: Easy [utilities], [ranges], and [iterators] - [C++]WG21月次提案文書を眺める(2020年6月)
- P1642R4 Freestanding Library: Easy [utilities], [ranges], and [iterators] - [C++]WG21月次提案文書を眺める(2020年7月)
- P1642R5 Freestanding Library: Easy [utilities], [ranges], and [iterators] - [C++]WG21月次提案文書を眺める(2020年12月)
- P1642R6 Freestanding Library: Easy [utilities], [ranges], and [iterators] - [C++]WG21月次提案文書を眺める(2021年06月)
- P1642R7 Freestanding Library: Easy [utilities], [ranges], and [iterators] - [C++]WG21月次提案文書を眺める(2021年10月)
このリビジョンでの変更は
move_only_function
、out_ptr
を含めないようにしたinvoke_r, zip, zip_transform, adjacent, adjacent_transform, to_underlying, unreachable, views::chunk_by, views::chunk, views::slide, views::join_with, ranges::to
及びP2387をフリースタンディングライブラリ機能として含めるようにした
などです。
この提案はC++23を目指してLWGのレビュー待ちをしています。
P1673R7 A free function linear algebra interface based on the BLAS
標準ライブラリに、BLASをベースとした密行列のための線形代数ライブラリを追加する提案。
以前の記事を参照
- P1673R3 A free function linear algebra interface based on the BLAS - [C++]WG21月次提案文書を眺める(2021年04月)
- P1673R4 A free function linear algebra interface based on the BLAS - [C++]WG21月次提案文書を眺める(2021年08月)
- P1673R5 A free function linear algebra interface based on the BLAS - [C++]WG21月次提案文書を眺める(2021年10月)
- P1673R6 A free function linear algebra interface based on the BLAS - [C++]WG21月次提案文書を眺める(2021年12月)
このリビジョンでの変更は、タイポの修正と提案する文言の調整などです。
P1674R1 Evolving a Standard C++ Linear Algebra Library from the BLAS
C++標準ライブラリに提案する線形代数ライブラリの設計に関して記述した文書。
これはP1673(1つ上)の設計について記述した文書でもあります。
BLASをベースに、それをC++のインターフェスによってラップし、C++のイディオムやコアガイドラインに沿うように抽象化していくとともに、その際に生じた問題やその解決について述べられています。
P1684R2 mdarray
: An Owning Multidimensional Array Analog of mdspan
多次元配列クラスmdarray
の提案。
このリビジョンでの変更は
- 全体的なtypoや指定漏れの修正
range
コンストラクタの追加- デフォルトのコンテナ型を
std::vector
とした - 内部コンテナへのアクセス関数を削除(勝手に
resize()
等ができてしまうため) mdspan
からの変換コンストラクタを追加mdarray
の領域へのmdspan
を返す.view()
メンバ関数の追加
などです。
P1967R5 #embed
- a simple, scannable preprocessor-based resource acquisition method
コンパイル時(プリプロセス時)にバイナリデータをインクルードするためのプリプロセッシングディレクティブ#embed
の提案。
以前の記事を参照
- P1967R3
#embed
- a simple, scannable preprocessor-based resource acquisition method - [C++]WG21月次提案文書を眺める(2021年04月) - P1967R4
#embed
- a simple, scannable preprocessor-based resource acquisition method - [C++]WG21月次提案文書を眺める(2021年06月)
このリビジョンでの変更は
- 実装者などからのフィードバックにより、構文の変更
- 提案する文言の改善
- WG14への提案とWG21への提案を分離した
__has_embed
の変更- 空のリソースに対しては1ではなく2を返す
limit
パラメータの引数について、最低でも1回はマクロ展開が行われるようにした
などです。
このリビジョンでは、empty
パラメータがis_empty
に変更されています。
// empty引数 // リソースが空の場合に指定されたpp-tokenのリストを展開する constexpr const char x[] = { #embed "empty_file.dat" \ is_empty((char)-1) }; // sizeof(x) == 1 // x[0] == -1 or 255
__has_embed<header-name>
はheader-name
に指定されたリソースが使用可能であるかを問い合わせるもので、__has_include
に対応するものです。その結果は
0
: リソースが見つからない、もしくは、指定された追加のパラメータが利用可能でない場合1
: リソースが存在し空ではなく、追加のパラメータが利用可能な場合2
: リソースが存在し空であり、追加のパラメータが利用可能な場合
となります。
また、これにより#embed
と#__has_embed
の間でTOCTOU問題が発生しますが、同じことは#include
と__has_include
の間でも発生しており、それは現在コンパイラによって回避されています(一度読んだファイルをキャッシュすることで回避されている)。#embed
も既存コンパイラのそうした実装に乗っかることで問題を回避できます。
P2071R2 Named universal character escapes
ユニバーサル文字名として、16進エスケープシーケンスの代わりにユニコードの規定する文字名を使用できるようにする提案。
以前の記事を参照
このリビジョンでの変更は、CWGからのフィードバックに基づく提案する文言の改善です。
この提案は既にCWGのレビューを終えており、C++23に向けて次の全体会議で投票にかけられる予定です。
P2093R14 Formatted output
std::format
によるフォーマットを使用しながら出力できる新I/Oライブラリstd::print
の提案。
以前の記事を参照
- P2093R0 Formatted output - [C++]WG21月次提案文書を眺める(2020年6月)
- P2093R1 Formatted output - [C++]WG21月次提案文書を眺める(2020年7月)
- P2093R2 Formatted output - [C++]WG21月次提案文書を眺める(2020年10月)
- P2093R3 Formatted output - [C++]WG21月次提案文書を眺める(2021年1月)
- P2093R4 Formatted output - [C++]WG21月次提案文書を眺める(2021年2月)
- P2093R5 Formatted output - [C++]WG21月次提案文書を眺める(2021年3月)
- P2093R6 Formatted output - [C++]WG21月次提案文書を眺める(2021年4月)
- P2093R7 Formatted output - [C++]WG21月次提案文書を眺める(2021年7月)
- P2093R8 Formatted output - [C++]WG21月次提案文書を眺める(2021年8月)
- P2093R9 Formatted output - [C++]WG21月次提案文書を眺める(2021年9月)
- P2093R10 Formatted output - [C++]WG21月次提案文書を眺める(2021年11月)
- P2093R12 Formatted output - [C++]WG21月次提案文書を眺める(2022年01月)
- P2093R13 Formatted output - [C++]WG21月次提案文書を眺める(2022年02月)
このリビジョンでの変更は、提案する文言の修正や改善です。
この提案はLWGでのレビューを終え、C++23に向けて次の全体会議で投票にかけられる予定です。
P2174R1 Compound Literals
C99から存在している複合リテラル(compound literal)をC++でもサポートする提案。
このリビジョンでの変更は、複合リテラルの生成するオブジェクトの値カテゴリを調整した事です。
以前の提案では複合リテラル(式)の値カテゴリはprvalueとすることを提案していました。この提案では複合リテラルで使用可能な型をtrivially destructibleな型のみに制限したうえで、複合リテラルの結果はそのスコープに導入される新しい変数を参照するlvalueとなるようになりました。
これによって、C++でも複合リテラルによって生成した匿名のバッファを安全に使用できるようになるなど、C言語での複合リテラルとほぼ同等に使用できるようになり、C言語への後方互換性が向上します。
char *ptr = strcat((char [100]){0}, "like this"); // ok、安全
P2198R5 Freestanding Feature-Test Macros and Implementation-Defined Extensions
フリースタンディング処理系でも使用可能なライブラリ機能について、機能テストマクロを追加する提案。
以前の記事を参照
- P2198R0 Freestanding Feature-Test Macros and Implementation-Defined Extensions - [C++]WG21月次提案文書を眺める(2020年07月)
- P2198R1 Freestanding Feature-Test Macros and Implementation-Defined Extensions - [C++]WG21月次提案文書を眺める(2020年10月)
- P2198R2 Freestanding Feature-Test Macros and Implementation-Defined Extensions - [C++]WG21月次提案文書を眺める(2021年07月)
- P2198R3 Freestanding Feature-Test Macros and Implementation-Defined Extensions - [C++]WG21月次提案文書を眺める(2021年11月)
- P2198R4 Freestanding Feature-Test Macros and Implementation-Defined Extensions - [C++]WG21月次提案文書を眺める(2021年12月)
このリビジョンでの変更は、__cpp_lib_bind_back, __cpp_lib_ranges_chunk, __cpp_lib_ranges_chunk_by, __cpp_lib_ranges_join_with, __cpp_lib_ranges_slide, __cpp_lib_ranges_to_container, __cpp_lib_reference_from_temporary, __cpp_lib_unreachable
をフリースタンディングとして追加したことなどです。
この提案は再びC++23に向けて作業されており、現在はLEWGでの最終投票をパスしています。
P2266R3 Simpler implicit move
return
文における暗黙のムーブを改善する提案。
以前の記事を参照
- P2266R0 Simpler implicit move - [C++]WG21月次提案文書を眺める(2021年01月)
- P2266R1 Simpler implicit move - [C++]WG21月次提案文書を眺める(2021年03月)
- P2266R2 Simpler implicit move - [C++]WG21月次提案文書を眺める(2021年09月)
このリビジョンでの変更は、この提案の内容に関してAnnexCに追記した事などです。
この提案の採択によって、ローカル右辺値参照をそのまま返そうとするときの型が変更されます。
decltype(auto) f(int&& x) { return (x); } // 戻り値型はint&&になる、以前はint& int& g(int&& x) { return x; } // ill-formedになる、以前はwell-formed
この提案CWGでのレビューを終え、次の全体会議で投票にかけられる予定です。
P2278R3 cbegin should always return a constant iterator
std::ranges::cbegin/cend
を拡張して、常にconst_iterator
を返すようにする提案。
以前の記事を参照
- P2278R0 cbegin should always return a constant iterator - [C++]WG21月次提案文書を眺める(2021年01月)
- P2278R1 cbegin should always return a constant iterator - [C++]WG21月次提案文書を眺める(2021年09月)
- P2278R2 cbegin should always return a constant iterator - [C++]WG21月次提案文書を眺める(2021年11月)
このリビジョンでの変更は、views::all_const
をviews::as_const
に名前を戻したことなどです。
この提案はLWGでのレビュー中です。
P2280R4 Using unknown references in constant expressions
定数式での参照のコピーを許可する提案。
以前の記事を参照
- P2280R0 Using unknown references in constant expressions - [C++]WG21月次提案文書を眺める(2021年01月)
- P2280R1 Using unknown references in constant expressions - [C++]WG21月次提案文書を眺める(2021年02月)
- P2280R2 Using unknown references in constant expressions - [C++]WG21月次提案文書を眺める(2021年05月)
- P2280R3 Using unknown references in constant expressions - [C++]WG21月次提案文書を眺める(2021年08月)
このリビジョンでの変更は、提案する文言の調整のみです。
この提案は既にCWGでのレビューを終えており、次の全体会議で投票にかけられる予定です。
P2286R7 Formatting Ranges
任意の範囲を手軽に出力できる機能を追加する提案。
以前の記事を参照
- P2286R0 Formatting Ranges - [C++]WG21月次提案文書を眺める(2021年1月)
- P2286R1 Formatting Ranges - [C++]WG21月次提案文書を眺める(2021年2月)
- P2286R2 Formatting Ranges - [C++]WG21月次提案文書を眺める(2021年8月)
- P2286R3 Formatting Ranges - [C++]WG21月次提案文書を眺める(2021年11月)
- P2286R4 Formatting Ranges - [C++]WG21月次提案文書を眺める(2021年11月)
- P2286R5 Formatting Ranges - [C++]WG21月次提案文書を眺める(2022年01月)
このリビジョンでの変更は、提案する文言の調整のみのようです。
P2300R5 std::execution
P0443R14のExecutor提案を置き換える、任意の実行コンテキストで任意の非同期処理を構成・実行するためのフレームワークおよび非同期処理モデルの提案。
以前の記事を参照
- P2300R0
std::execution
- WG21月次提案文書を眺める(2021年06月) - P2300R1
std::execution
- WG21月次提案文書を眺める(2021年07月) - P2300R2
std::execution
- WG21月次提案文書を眺める(2021年11月) - P2300R3
std::execution
- WG21月次提案文書を眺める(2021年12月)
このリビジョンでの変更は
start_detached
は引数にvoid
senderを要求するようにしたreciever
コンセプトはエラーチャネルにexception_ptr
を使用しないようになったsender_of
コンセプトとconnect
カスタマイゼーションポイントでは、receiver
がすべての完了を受信できる必要があることが要求されるようになったget_completion_signatures
はcompletion_signatures
かdependent_completion_signatures
のどちらかを返すようにしたmake_completion_signatures
をよりジェネリックにしたreceiver_adaptor
は派生クラスの.get_env()
メンバ関数を考慮するようになったjust, just_error, just_stopped, into_variant
はカスタマイゼーションポイントととして再指定された
などです。
この提案は現在LWGに転送するためのLEWGでの最終投票待ちをしています。
P2302R4 std::ranges::contains
新しいアルゴリズムとしてstd::ranges::contains
を追加する提案。
- P2302R0 Prefer std::ranges::contains over std::basic_string_view::contains - [C++]WG21月次提案文書を眺める(2021年2月)
- P2302R1 std::ranges::contains - [C++]WG21月次提案文書を眺める(2021年11月)
- P2302R2 std::ranges::contains - [C++]WG21月次提案文書を眺める(2021年12月)
- P2302R3 std::ranges::contains - [C++]WG21月次提案文書を眺める(2022年01月)
このリビジョンでの変更は提案する文言の修正です。
この提案はLWGのレビューを終えて、C++23に向けて次の全体会議で投票にかけられる予定です。
P2322R6 ranges::fold
range
アルゴリズムであるranges::fold
の提案。
以前の記事を参照
- P2322R0 ranges::fold - [C++]WG21月次提案文書を眺める(2021年02月)
- P2322R1 ranges::fold - [C++]WG21月次提案文書を眺める(2021年03月)
- P2322R2 ranges::fold - [C++]WG21月次提案文書を眺める(2021年04月)
- P2322R3 ranges::fold - [C++]WG21月次提案文書を眺める(2021年06月)
- P2322R4 ranges::fold - [C++]WG21月次提案文書を眺める(2021年09月)
- P2322R5 ranges::fold - [C++]WG21月次提案文書を眺める(2021年10月)
このリビジョンでの変更は、提案する文言の修正です。
この提案はLWGでのレビューを終えて、次の全体会議で投票にかけられる予定です。
P2400R3 Library Evolution Report: 2021-09-28 to 2022-01-25
2021年9月から2022年1月にかけての、LEWGでのミーティングについてのまとめ。
どれくらいミーティングを行ったのか、おおまかな機能単位についての進行状況、レビューを行った提案についての議論の状況などが記載されています。
P2408R5 Ranges iterators as inputs to non-Ranges algorithms
非Rangeアルゴリズムのイテレータに対する名前付き要件を、イテレータコンセプトで置き換える提案。
以前の記事を参照
- P2408R0 Ranges views as inputs to non-Ranges algorithms - WG21月次提案文書を眺める(2021年07月)
- P2408R1 Ranges views as inputs to non-Ranges algorithms - WG21月次提案文書を眺める(2021年09月)
- P2408R2 Ranges iterators as inputs to non-Ranges algorithms - WG21月次提案文書を眺める(2021年10月)
- P2408R4 Ranges iterators as inputs to non-Ranges algorithms - WG21月次提案文書を眺める(2021年11月)
このリビジョンでの変更は、提案する文言の調整です。
この提案はLWGでのレビューを終えて、次の全体会議で投票にかけられる予定です。
P2472R2 make function_ref
more functional
function_ref
に適応的に型消去させるためのヘルパ関数make_function_ref()
を追加する提案。
以前の記事を参照
- P2467R0 Support exclusive mode for fstreams - WG21月次提案文書を眺める(2021年10月)
- P2467R1 Support exclusive mode for fstreams - WG21月次提案文書を眺める(2022年02月)
このリビジョンでの変更は
- 提案する文言の追加
function_ref
に、参照の代わりにポインタを受け取る3つ目のコンストラクタを追加function_ref
の推論補助を追加
などです。
この提案はC++23に向けて作業されることになったようです。
P2505R2 Monadic Functions for std::expected
std::optional
のMonadic interfaceをstd::expected
にも導入する提案。
以前の記事を参照
このリビジョンでの変更は、CGG(libstdc++)での実装と例へのリンク追加と提案する文言の修正などです。
この提案はバグフィックスであるとしてC++23をターゲットにすることになったようです。
P2510R2 Formatting pointers
std::format
について、ポインタ型のフォーマットを充実させる提案。
以前の記事を参照
- P2510R0 Formatting pointers - WG21月次提案文書を眺める(2021年12月)
- P2510R1 Formatting pointers - WG21月次提案文書を眺める(2022年03月)
このリビジョンでの変更は、例(比較表)におけるフォーマットエラーを修正したこと、参照実装へのリンクを追加した事です。
P2538R1 ADL-proof std::projected
C++20 Rangeアルゴリズムが不必要な型の完全性要求をしないようにする提案。
このリビジョンでの変更は、コンパイルエラーの例を追記したことなどです。
この提案はC++23に向けて、LEWGの最終投票待ちをしています。
P2539R1 Should the output of std::print
to a terminal be synchronized with the underlying stream?
提案中のstd::print
(P2093)が出力するストリームについて、同じストリームに対する他の出力との同期を取るようにする提案。
このリビジョンでの変更は、例を追加したこと、提案する文言を追加した事などです。
P2542R1 views::concat
同じ要素型を持つ異なる型の範囲を連結するRangeファクトリ、views::concat
の提案。
このリビジョンでの変更は
- 元の範囲が
!common_range && random_access_range && sized_range
であるときにconcat_view
をcommon_range
とするのをやめた concat
可能な型を示す説明専用のコンセプトconcatable
を追加- 主に入力範囲の値型の互換性に関する要求をまとめたもの
などです。
P2546R1 Debugging Support
標準ライブラリにデバッグサポートの為のユーティリティを追加する提案。
以前の記事を参照
このリビジョンでの変更は、std::breakpoint()
の何もしない可能性がある実装についてのコメントを削除、SG15における投票結果を追記。
この提案はC++26に向けて、LEWGでのレビュー中です。
P2559R0 Plan for Concurrency Technical Specification Version 2
Concurrency TS v2発効に向けた作業計画書。
現在のConcurrency TS v2に向けては次の2つの提案が採択されています
次の提案は、Concurrency TS v2入りを目指してレビュー中です
- P0290R2 synchronized_value
- P0561R6
- Deferred Reclamation RAII Interface - P1478R7 Byte-wise Atomic memcpy
- P2396R0 Concurrency TS 2 Fixes
- P1202R4 Asymmetric Fences
- LEWGでのレビュー待ち
- P2535R0 Message Fences
- Concurrency study groupのレビュー待ち
予定では、2022年中にLEWGでのレビューを完了し、2023年後半に正式発効することを目指しています。
P2573R0 = delete("should have a reason");
関数のdelete
指定にメッセージを付加できるようにする提案。
関数のdelete
指定はC++11で導入され、特に、クラスの特殊メンバ関数の暗黙生成を抑制するために対応する宣言をプライベートで宣言だけしておくイディオムを置き換えることが目的でした。しかし、= delete;
は特殊メンバ関数だけではなくあらゆる関数に拡張され、さらに強力な機能となりました。
導入から10年が経ち振り返ってみれば、この機能はライブラリ関数の誤使用を防止するC++11の重要な改善の1つだったと言ってよく、Andrew's C/C++ Token Count Dataset 2019.で調べてみるとその利用は4万件を超えており、標準ライブラリ内部でもより広いコミュニティ全体でも広く採用されています。
しかしその診断メッセージには問題があり、delete
指定された関数が呼ばれた場合には単に削除されているとしか表示されず、なぜ削除されているのかがユーザからは不明瞭になっています。これと同様の問題は、[[deprecated]]
や[[nodiscard]]
でも報告され、これらはそれぞれC++14とC++20で理由を含むメッセージを指定できるように拡張されました。
この提案は、それらと同様に= delete
もメッセージを付加できるように拡張しようとするものです。
提案している構文は= delete("...");
という形のもので、delete()
に渡す文字列で理由を指定し、コンパイラはその関数が選択された場合のエラーメッセージにその文字列を出力します。
提案文書より、利用例
// フリー関数 void newapi(); void oldapi() = delete("This old API is outdated and already been removed. Please use newapi() instead."); // 関数テンプレート template<typename T> struct A {/* ... */}; template<typename T> A<T> factory(const T&) {/* process lvalue */} template<typename T> A<T> factory(const T&&) = delete("Using rvalue to construct A may result in dangling reference"); // メンバ関数 struct MoveOnly { // ... (with move members defaulted or defined) MoveOnly(const MoveOnly&) = delete("Copy-construction is expensive; please use move construction instead."); MoveOnly& operator=(const MoveOnly&) = delete("Copy-assignment is expensive; please use move assignment instead."); };
std::unique_ptr
での利用例
// [unique.ptr.single.general] namespace std { template<class T, class D = default_delete<T>> class unique_ptr { public: // ... // disable copy from lvalue unique_ptr(const unique_ptr&) = delete( "unique_ptr<T> resembles unique ownership, so copy is not supported. Use move operations instead."); unique_ptr& operator=(const unique_ptr&) = delete( "unique_ptr<T> resembles unique ownership, so copy is not supported. Use move operations instead."); } } // [memory.syn] namespace std { // ... template<class T> constexpr T* addressof(T& r) noexcept; template<class T> const T* addressof(const T&&) = delete("Cannot take address of rvalue."); // ... template<class T, class... Args> // T is not array constexpr unique_ptr<T> make_unique(Args&&... args); template<class T> // T is U[] constexpr unique_ptr<T> make_unique(size_t n); template<class T, class... Args> // T is U[N] unspecified make_unique(Args&&...) = delete( "make_unique<U[N]>(...) is not supported; perhaps you mean make_unique<U[]>(N) instead?"); } // [basic.string.general] namespace std { template<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT>> class basic_string { public: // ... basic_string(nullptr_t) = delete("Construct a string from a null pointer is undefined behavior."); }
これによって、ライブラリ開発者は今までの「あなたがやろうとしていることはわかるしそれは間違っている」というメッセージに加えて、「なぜ間違っているのか、推奨される方法を示すこともできる」という選択肢を手に入れることができ、ユーザーエクスペリエンスを改善することができます。
C++23の設計凍結時期は既に過ぎており、原則としてこの提案をC++23に含めることはできません。しかし、この提案の内容は既存機能の改善であり、=delete;
のより広い採用と既存ライブラリの使いやすさの向上に不可欠なものであり後2年ほど待たせるべきでは無く、実装も簡単(clangのフォークで実装済み)である、と筆者の方は主張しておりC++23に向けて提案しています。
P2574R0 2022-05 Library Evolution Polls
2022年の5月に予定されている、LEWGでの全体投票の予定表。
次の提案が、LWGに進むための投票にかけられます。
- P1885R10 Naming Text Encodings to Demystify Them
- P0792R8 function_ref
- P1223R3 find_last
- P1169R3 Static operator()
- P2553R1 Make mdspan size_type Controllable
- P2554R0 C-Array Interoperability Of mdspan
- P2540R0 Empty Product For Certain Views
- P2538R0 ADL-Proof projected
- P2520R0 move_iterator Should Be A Random Access Iterator
- P2499R0 string_view Range Constructor Should Be Explicit
- P2549R0 unexpected Should Have error As Member Accessor
- P2517R0 Add A Conditional noexcept Specification To apply
- P2300R5 std::execution
- C++26向け
- P1083R5 resource_adaptor
- C++26向け
- P1202R4 Asymmetric Fences
- Concurency TS v2向け
最後の3つ以外はすべてC++23を目指しています。
P2577R0 C++ Modules Discovery in Prebuilt Library Releases
ビルド済みモジュールライブラリ配布のための規則についての提案。
これは、P2473R1の代替案となる提案です。P2473R1では、モジュール名とファイル名が対応していることを提案していましたがこの点についてコンセンサスを得られなかったようで、ライブラリ自体により近いメタデータファイルを読み取ることができるより高いレベルの抽象化が必要であるという指針が示されたようです。ただし、それは結局メタデータファイルの依存関係やビルドに必要なメタデータファイルを決定する方法などの問題を生みますが、これをどのように実現するかについてはまだコンセンサスを得られていないようです。
この提案は、ビルドシステムがビルド済みモジュールライブラリを使用するために、まず最初にそのライブラリにまつわるメタデータファイルを発見する方法についてのものです。
この提案では、今日のビルドシステムがビルド済みライブラリを利用する際に主にそのリンカ引数を取得するためにパッケージマネージャーと対話し、ビルド済みバイナリを正しく使用する方法をパッケージマネージャから取得していることに着目しています。
この実装そのものは完全に実装定義であり取得する情報(リンカ引数)の形式や意味も実装定義ですが、ビルドシステムがビルド済みライブラリを利用する際にそれらの情報を必要とし、取得しているという点は共通しています。また、これらの情報は実装定義の方法によってファイルに保存されることも共通しています。
この提案は、ビルド済みモジュールのメタデータファイルを決定論的に命名し、ビルドシステムはリンカ引数取得プロセスにおいて同時にそのメタデータファイルを取得し(リンカ引数からメタデータファイルへの変換を行うことでメタデータファイル名を得る)、それをパースすることでビルド済みモジュールライブラリの利用に必要な情報(バイナリの場所と名前、コンパイル時引数、依存関係など)を取得するというプロセス、及びそのメタデータファイルが現在のパッケージマネージャが配布するリンカ引数等の情報と同様に配布されることを提案しています。
具体的な配布形態や配布手段、メタデータがビルドシステムに伝達される手段などは実装定義となりますが、これは現在C++ビルド済みライブラリを使用するための要件でもあり、既に実装され広く使用されているはずです。
この提案によるアプローチのメリット
- ODR違反の緩和
- 既存のセマンティクスのみを使用する
提案では、GNU/Linux環境(GNU Linkerを使用)を例にこれらのことの実装例を解説しています。この環境の場合、ライブラリはpkg-config名によって指定され、pkg-configファイルによってライブラリおよび依存ライブラリのリンカ引数が取得されます。
GNU/Linux環境の場合リンカ引数からモジュールメタデータファイルへの変換は簡単で、例えば取得されたライブラリファイル名(libfoo.a, libbar.so
)の拡張子を変更してモジュールメタデータファイル(libfoo.meta-ixx-info, libbar.meta-ixx-info
)を取得します。メタデータファイルがない場合はそのライブラリはモジュールを提供しないものと見做せばよく、メタデータファイルにはコンパイル時引数(コンパイラとリンカへの引数)およびモジュール依存関係グラフが含まれており(いる必要があり)、これを全て結合することでモジュールを正しく使用するために必要な情報の全てを取得することができます。
Windows環境におけるMT/MDオプションのように、的リンクと動的リンクでオプションが変化するような場合でも、現在のビルド設定からまずそのオプジョンを判別し、それに従って最初に探しに行くライブラリを変化させることで後の処理を共通化し、ビルド条件分岐を簡易に処理することができます。