文書の一覧
全部で36本あり、SG22(C/C++相互互換性に関する研究グループ)のCの提案を除くと32本になります。
- 採択された文書
- その他文書
- N4884 WG21 2021-02 Virtual Meeting Minutes of Meeting
- N4885 Working Draft, Standard for Programming Language C++
- N4886 Editors’ Report - Programming Languages - C++
- P0448R4 A strstream replacement using span as buffer
- P0958R3 Networking TS changes to support proposed Executors TS
- P1018R9 C++ Language Evolution status 🦠 pandemic edition 🦠 2021/01–2021/03 - 2021/01–2021/03
- P1315R7 secure_clear
- P1425R4 Iterators pair constructors for stack and queue
- P1518R1 Stop overconstraining allocators in container deduction guides
- P1518R2 Stop overconstraining allocators in container deduction guides
- P1875R2 Transactional Memory Lite Support in C++
- P2025R2 Guaranteed copy elision for return variables
- P2041R1 template = delete
- P2066R6 Suggested draft TS for C++ Extensions for Minimal Transactional Memory
- P2093R5 Formatted output
- P2210R2 Superior String Splitting
- P2242R2 Non-literal variables (and labels and gotos) in constexpr functions
- P2266R1 Simpler implicit move
- P2299R0 mdspan and CTAD
- P2314R1 Character sets and encodings
- P2322R1 ranges::fold
- P2325R1 Views should not be required to be default constructible
- P2328R0 join_view should join all views of ranges
- P2330R0 WG21 2021-02 Virtual Meeting Record of Discussion
- P2332R0 Establishing std::hive as replacement name for the proposed std::colony container
- P2333R0 2021 Winter Library Evolution Poll Outcomes
- P2334R0 Add support for preprocessing directives elifdef and elifndef
- P2338R0 Freestanding Library: Character primitives and the C library
- P2339R0 Contract violation handlers
- P2340R0 Clarifying the status of the ‘C headers’
- P2400R0 Library Evolution Report
採択された文書
P2313R0 Core Language Working Group "tentatively ready" issues for the February, 2021 meeting
2月の会議で採択されたコア言語のIssue解決の一覧。
解決されたIssueは一件だけです。
- 2470. Multiple array objects providing storage for one object
-
unsigned char/std::byte
の配列上に別のオブジェクトを構築する時、新しく作成されるオブジェクトにどの配列がストレージを提供したのかが曖昧にならないようにした。
-
その他文書
N4884 WG21 2021-02 Virtual Meeting Minutes of Meeting
2021年2月22日(米国時間)に行われた、WG21全体会議の議事録。
CWG/LWG/LEWGの投票の様子などが記載されています。
N4885 Working Draft, Standard for Programming Language C++
N4886 Editors’ Report - Programming Languages - C++
↑の変更点をまとめた文書。
2月の会議で採択された提案とコア言語/ライブラリのIssue解決が適用されています。
P0448R4 A strstream replacement using span as buffer
長い間非推奨のまま代替手段のなかったstd::strstream
の代替となるstd::span
によるspanstream
を追加する提案。
以前の記事を参照
このリビジョンでの変更は、LWGのレビューでのフィードバックに基づいて、提案する文言を調整したことです。
この提案は既にこのリビジョンのLWGでのレビューと投票を終えており、全体会議での投票待ちをしています。そこで反対が無ければ、C++23に導入されます。
P0958R3 Networking TS changes to support proposed Executors TS
Networking TSのExecutorの依存部分をP0443のExecutor提案の内容で置き換える提案。
以前の記事を参照
このリビジョンでの変更は、executor
コンセプトについてsatisfiesを使用していた所をmodelへ変更したことや、timer
やsocket
などにbasic
のプリフィックスを加えたことなど、文面の調整です。
P1018R9 C++ Language Evolution status 🦠 pandemic edition 🦠 2021/01–2021/03 - 2021/01–2021/03
EWG(コア言語への新機能追加についての作業部会)が2021/01–2021/03の間に議論した提案やIssueのリストや将来の計画、テレカンファレンスの状況などをまとめた文書。
- P2223R1 Trimming whitespaces before line splicing
- P2201R0 Mixed string literal concatenation
- P2186R1 Removing Garbage Collection Support
- P2173R0 Attributes on Lambda-Expressions
- P2156R1 Allow Duplicate Attributes
- P2013R3 Freestanding Language: Optional ::operator new
- P1949R6 C++ Identifier Syntax using Unicode Standard Annex 31
- P1938R2 if consteval
- P1847R3 Make declaration order layout mandated
- P1401R4 Narrowing contextual conversions to bool
これらの提案はコンセンサスが得られ、CWGに転送されています。また、その議論や投票の際の賛成・反対のコメントが記載されています。
また、次の提案はライブラリ機能についてのものですが、その内容を言語サポートとすべきかが投票にかけられました。
Executorのプロパティ指定の方法は独立したライブラリ機能として提案されていますが、これを言語サポートする方向でコンセンサスが得られたようです。
P1315R7 secure_clear
特定のメモリ領域の値を確実に消去するための関数secure_clear()
の提案。
以前の記事を参照
- P1315R5 :
secure_clear
- [C++]WG21月次提案文書を眺める(2020年4月) - P1315R6 :
secure_clear
- [C++]WG21月次提案文書を眺める(2020年12月)
このリビジョンでの変更は、C言語に向けた文言の表現の選択肢の改善や、選択されなかったものの削除、C/C++委員会での投票結果の記載などです。
P1425R4 Iterators pair constructors for stack and queue
std::stack
とstd::queue
に、イテレータペアを受け取るコンストラクタを追加する提案。
以前の記事を参照
P1425R2 Iterators pair constructors for stack and queue - [C++]WG21月次提案文書を眺める(2021年01月)
P1425R3 Iterators pair constructors for stack and queue - [C++]WG21月次提案文書を眺める(2021年02月)
このリビジョンでの変更は、2つに分かれていた機能テストマクロを__cpp_lib_adaptor_iterator_pair_constructor
一つに統一した事と、提案する文言の調整です。
このリビジョンは既にLWGのレビューと投票が済んでおり、次の会議の全体投票を待っています。
P1518R1 Stop overconstraining allocators in container deduction guides
↓
P1518R2 Stop overconstraining allocators in container deduction guides
コンテナとコンテナアダプタのクラステンプレート引数推論時の振る舞いを修正し、pmr
コンテナの初期化を行いやすくする提案。
std::pmr::monotonic_buffer_resource mr; std::pmr::polymorphic_allocator<int> a = &mr; std::pmr::vector<int> pv(a); // CTADを使用しない構築、全てok auto s1 = std::stack<int, std::pmr::vector<int>>(pv); auto s2 = std::stack<int, std::pmr::vector<int>>(pv, a); auto s3 = std::stack<int, std::pmr::vector<int>>(pv, &mr); // CTADを使用する構築 auto ds1 = std::stack(pv); auto ds2 = std::stack(pv, a); auto ds3 = std::stack(pv, &mr); // NG!
※CTAD = Class Template Argument Deduction (クラステンプレートの実引数推定)
stack
をはじめとするコンテナアダプタのアロケータ引数は、クラステンプレートのテンプレートパラメータの推論に寄与しません。従って、対応するCTADを使用しない構築の時と同様にコンテナ型からの推論を行うのが望ましいはずです。
namespace std { template<typename Container, typename Allocator> class stack; // stackの2引数推論補助 template<class Container, class Allocator> stack(Container, Allocator) -> stack<typename Container::value_type, Container>; }
このことは何か意図があってのものではなく、単に見落とされただけだと思われるので修正しようとする提案です。
なぜこのようなことが起こるのかというと、コンテナアダプタの推論補助について次のような規定が存在しているためです。
A deduction guide for a container adaptor shall not participate in overload resolution if any of the following are true: - ... - It has an Allocator template parameter and a type that does not qualify as an allocator is deduced for that parameter. - ...
[N4861 container.adaptors.general]/4.4
アロケータとしての資格のない型がアロケータ型として渡されている場合、そのアロケータ型がテンプレートパラメータの推論に寄与しないとしても、アロケータ型を受け取る推論補助を無効化してしまいます。
アロケータとしての資格がある型というのは実装定義ですが、最小の要件の一つとして、アロケータ型A
についてメンバ型A::value_type
が利用可能であることがあります([container.requirements.general]/17)。
auto ds3 = std::stack(pv, &mr); // NG!
先程の例のここでは、第二引数の&mr
の型はstd::pmr::monotonic_buffer_resource*
というポインタ型であって、当然メンバ型を持っておらず、アロケータとしての資格がある型ではないため対応する推論補助は考慮されなくなります。ただ一方で、std::pmr::vector<int>
はstd::pmr::monotonic_buffer_resource*
をアロケータとして利用して構築することができます。
さらに、似た問題がstd::vector
そのものにも存在しています。
std::pmr::monotonic_buffer_resource mr; std::pmr::polymorphic_allocator<int> a = &mr; std::pmr::vector<int> pv(a); // CTADによらない構築、全てok auto v1 = std::vector<int, std::pmr::polymorphic_allocator<int>>(pv); auto v2 = std::vector<int, std::pmr::polymorphic_allocator<int>>(pv, a); auto v3 = std::vector<int, std::pmr::polymorphic_allocator<int>>(pv, &mr); // CTADを使用する構築 auto dv1 = std::vector(pv); auto dv2 = std::vector(pv, a); auto dv3 = std::vector(pv, &mr); // NG!
ここでの問題は先ほどとは少し違っていて、暗黙に生成される推論補助を利用する経路で問題が起きています。
推論補助が無い場合、対応するコンストラクタから推論補助を生成してテンプレートパラメータを推論しようとします。ここで対応しているコンストラクタはアロケータを受け取るコピーコンストラクタです。
namespace std { template<typename T, typename Allocator> class vector { // アロケータを受け取るコピーコンストラクタ vector(const vector<T, Allocator>&, const Allocator&); }; }
そして、第1引数からはT = int, Allocator = std::polymorphic_allocator<int>
が導出され、第2引数からはAllocator = std::pmr::monotonic_buffer_resource*
が導出されます。同一のパラメータに対して衝突する候補が発生しているので、推論は失敗しコンパイルエラーとなります。
この提案ではこれらの解決のために、すべてのコンテナのアロケータを受け取るコンストラクタ引数をstd::type_identity_t
で包むことでアロケータ引数をCTAD推論の対象から外し、またコンテナアダプタのアロケータ型がある場合の推論補助の要件を「コンテナ型が無く、アロケータ型がある場合」のように少し緩和します。
namespace std { template<typename T, typename Allocator> class vector { // 現在 vector(const vector<T, Allocator>&, const Allocator&); // この提案 vector(const vector<T, Allocator>&, const type_identity_t<Allocator>&); }; } void stack() { std::pmr::monotonic_buffer_resource mr; std::pmr::polymorphic_allocator<int> a = &mr; std::pmr::vector<int> pv(a); // この提案の後では、共にOK auto ds3 = std::stack(pv, &mr); auto dv3 = std::vector(pv, &mr); }
std::vector
の場合は、std::type_identity_t
によって第2引数の&mr
からAllocator
パラメータを推論しなくなるのでAllocator
が一つに定まるようになり、std::stack
の場合は文言の変更によって&mr
から推論されるアロケータ型の適格性がチェックされなくなるので既存の推論補助によって正しく推論が行われるようになります。
この提案の内容は標準ライブラリの主要な3実装がそれぞれ、誤って 先行して実装しているようです。特に連想コンテナはMSVCとClang(と一部GCCも)すでにこうなっているようです。
std::stack
推論補助 - cpprefjpstd::type_identity
- cpprefjp- テンプレート引数として使用するtype_identity_tはなんのため? - cpprefjp/site - Github
- P1518 進行状況
P1875R2 Transactional Memory Lite Support in C++
現在のトランザクショナルメモリTS仕様の一部だけを、軽量トランザクショナルメモリとしてC++へ導入する提案。
以前の記事を参照
変更履歴が無いため変更点はよくわかりませんが、おそらくP2066の議論の進行に伴って必要となった変更などを反映したのだと思われます。
P2025R2 Guaranteed copy elision for return variables
NRVO(Named Return Value Optimization)によるコピー省略を必須にする提案。
以前の記事を参照
この提案は主に明示的に注釈することで(N)RVOをオプトインする構文を追加するために、EWGに差し戻されました。
このリビジョンでは、その検討のセクションおよびABIレベルのコピー省略の問題についての説明のセクションを追加しています。
そこでは、[[nrvo]]
属性や変数宣言時のreturn
注釈、return explicit
文、関数宣言(定義)のreturn
指定など、様々な構文が検討されています。
P2041R1 template = delete
関数テンプレートがdelete
オーバーロードを提供可能なように、クラス/変数テンプレートでもdelete
指定オーバーロード(特殊化)を提供できるようにする提案。
複数の事を意味する同じ名前があり、それらのうちのいくつかは定義されるべきではないとき、現在はその定義を禁止するシンプルで簡易な方法がありません。変数・クラステンプレートについてdelete
指定できるようにすることで、一部の特殊化を禁止したり、逆に一部の特殊化だけを許可したりすることができるようになります。
// プライマリ変数テンプレートはdelete、特殊化は許可 template<typename> int x = delete; template<> int x<int> = 5; // 変数テンプレートの特定の特殊化を禁止 template<typename T> auto y = T(); template<> auto y<int> = delete; // プライマリクラステンプレートはdelete、特殊化は許可 template<typename> struct s = delete; template<> struct s<int> { }; // クラステンプレートの特殊化を禁止 template<typename> struct t { }; template<> struct t<int> = delete;
非テンプレートのクラスなどでは、delete
するクラスを定義するのではなく最初から定義しないようにすれば同じ効果が得られます。そのため、ここではテンプレートではないものまでdelete
指定できるようにすることは提案されていません。
P2066R6 Suggested draft TS for C++ Extensions for Minimal Transactional Memory
現在のトランザクショナルメモリTS仕様の一部だけを、軽量トランザクショナルメモリとしてC++へ導入する提案。
以前の記事を参照
- P2066R2 Suggested draft TS for C++ Extensions for Minimal Transactional Memory - [C++]WG21月次提案文書を眺める(2020年05月)
- P2066R3 Suggested draft TS for C++ Extensions for Minimal Transactional Memory - [C++]WG21月次提案文書を眺める(2020年09月)
- P2066R4 Suggested draft TS for C++ Extensions for Minimal Transactional Memory - [C++]WG21月次提案文書を眺める(2020年10月)
- P2066R5 Suggested draft TS for C++ Extensions for Minimal Transactional Memory - [C++]WG21月次提案文書を眺める(2021年02月)
このリビジョンの変更点は、R5で標準ライブラリのもののほとんどがatomicブロックでの使用を許可されましたが、そのうち同期の問題が発生しうるものを除外した事です。例えば、shared_ptr
やsynchronus_memory_resource
、タイムゾーンのデータベースなどが該当します。
P2093R5 Formatted output
p2093r4.html)
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月)
このリビジョンでの変更は、ostream
を取るオーバーロードをヘッダ分けしたことと、ostream
を取らないものの配置するヘッダの候補をリスト化した事です。現在は<io>
に配置することを提案しています。
この提案はSG16での議論とレビューを終えて、LEWGに送られました。非常に素早く作業が進行しているため、C++23に入る可能性は高そうです。
P2210R2 Superior String Splitting
現状のviews::split
の非自明で使いにくい部分を再設計する提案。
前回の記事を参照
- P2093R0 Formatted output - [C++]WG21月次提案文書を眺める(2020年8月)
- P2093R1 Formatted output - [C++]WG21月次提案文書を眺める(2021年1月)
このリビジョンでの変更は、現在のviews_split
(lazy_split
)にある問題の解決を含んだうえで文言を調整し、実装例を追記した事です。
この提案はLEWGでの議論が完了しLWGに転送する最終投票を待っていますが、C++20にDRとして適用するためにLWGで先行してレビューが完了しています。LEWGでの投票が問題なく終われば、C++23(C++20)導入に向けて全体会議での投票に進みます。
P2242R2 Non-literal variables (and labels and gotos) in constexpr functions
constexpr
関数において、コンパイル時に評価されなければgoto
やラベル、非リテラル型の変数宣言を許可する提案。
以前の記事を参照
- P2242R0 Non-literal variables (and labels and gotos) in constexpr functions - [C++]WG21月次提案文書を眺める(2020年10月)
- P2242R1 Non-literal variables (and labels and gotos) in constexpr functions - [C++]WG21月次提案文書を眺める(2021年02月)
このリビジョンでの変更は、機能テストマクロに関する議論を追記したことと、サンプルと文言の微修正です。
この提案の修正は実際にはconstexpr
関数で実行可能なものを増やしているわけではありませんが、__cpp_constexpr
の値を微増させています。検出が必要になるとは思えないけれどconstexpr
の許容範囲を広げるときに値を更新する方向性を支持している、ということが説明されています。
P2266R1 Simpler implicit move
return
文における暗黙のムーブを改善する提案。
以前の記事を参照
このリビジョンでの変更は、提案する文言のリファクタリングと、ラムダの内部でローカル変数がスローされるときにも、スローされる変数を暗黙ムーブするかのような文言になっている部分を修正する文言を追加した事です。
P2299R0 mdspan
and CTAD
提案中のstd::mdspan
のCTAD対応についての問題を報告する文書。
P0009R10で提案されているstd::mdspan
は、std::basic_mdspan
を基礎として、そのエイリアスとしてstd::mdspan
を定義しています。
template <class ElementType, ptrdiff_t... Extents> using mdspan = basic_mdspan<ElementType, extents<Extents...>>;
これは例えば次のように利用できます
int main() { // 何かメモリ領域 double* data = ...; // 静的サイズ mdspan<double, 64, 64> a1(data); // 動的サイズ mdspan<double, dynamic_extent, dynamic_extent> a2(data, 64, 64); // 静的+動的サイズ mdspan<double, 64, dynamic_extent> a3(data, 64); }
C++20からはエイリアステンプレートに対するCTADが利用可能となっているので、上記の2つめの例は次のように書けるはずです。
int main() { // 何かメモリ領域 double* data = ...; // 動的サイズ mdspan a2(data, 64, 64); }
冗長なdynamic_extent
指定を排除し非常に読みやすくなります。しかし、これはどうやら意図通りに動かないようです。
ここでは、std::mdspan<double>
を推論した後、std::basic_mdspan<double, extents<>>
を推論しインスタンス化します。これはstd::basic_mdspan
の動的エクステントのコンストラクタでstatic_assert
に引っかかりコンパイルエラーを起こします。
単純には、std::mdspan
に推論補助を追加すればこの問題の解決は図れるはずですが、現在の仕様ではエイリアステンプレートに推論補助を追加できません。かといって、std::mdspan
を単独のクラスにしてしまうとstd::basic_mdspan
との相互運用性がなくなるなど様々な問題が発生します。
この提案はこの問題の周知を図り、よりよい解決策を募るものです。
P2314R1 Character sets and encodings
規格文書中の ~ character setという言葉を明確に定義し直す提案。
以前の記事を参照
このリビジョンでの変更は、文言の修正とP2297R0との目的の差異を説明するセクションの追加、ロケール依存の実行文字集合(execution (wide) character set)の文言の場所をライブラリに移動した事です。
この提案は、既存の振る舞いを維持しながら、言葉の定義を明確にすることで字句解析におけるコア言語のルールの再構築を目指すものです。従って、EWGの負担は軽くなる筈、という事が説明されています。
P2322R1 ranges::fold
range
アルゴリズムであるranges::fold
の提案。
以前の記事を参照
このリビジョンでの変更は、以前にregular_invocable
コンセプトを用いていたところをinvocable
コンセプトに変更した事(regularであることは必要なかったため)と、以前にfold_first
などとしていた初項を範囲から補う関数ファミリを初項の提供有無でのオーバーロードに変更したことです。
以前に書いたサンプルは次のようになります。
std::vector<int> vec = {1, 2, 3, 4, 5}; int sum1 = std::ranges::fold(vec, 0, std::ranges::plus{}); int sum2 = std::ranges::fold(vec, std::ranges::plus{}); // sum1 == sum2 == 15 std::vector<std::string> vec2 = {"aaa", "bbb", "ccc"}; std::string concat1 = std::ranges::fold(vec2, std::ranges::plus{}); // concat1 == "aaabbbccc" std::string concat2 = std::ranges::fold_right(vec2, std::string{}, std::ranges::plus{}); std::string concat3 = std::ranges::fold_right(vec2, std::ranges::plus{}); // concat2 == concat3 == "cccbbbaaa"
P2325R1 Views should not be required to be default constructible
Viewとみなされる型にデフォルト構築可能性を要求しない様にする提案。
以前の記事を参照
このリビジョンでの変更は、パイプラインでの左辺値/右辺値の固定エクステントstd::span
の扱いに関する例を追加した事です。
std::span
はview
であるはずなのですが、固定エクステントの場合はデフォルト構築できないようになっています。これによって、右辺値と左辺値でそれぞれ異なる、非効率な結果が得られます
std::span<int, 5> s = /* ... */; // spanはviewではないため、transform_viewはコピーする代わりに`ref_view<span<int, 5>>`を保持する // sの寿命が先に尽きる場合、これはダングリング参照となる auto lvalue = s | views::transform(f); // spanはborrowed_rangeであるため、これはコンパイル可能 // ただ、sをコピーするのではなく、subrange<span<int, 5>::iterator>を保持する auto rvalue = std::move(s) | views::transform(f);
左辺値の場合はダングリングの危険があり、追加の間接参照が必要となります。右辺値の場合はダングリングの危険はないものの、2つのイテレータを保持する必要からspan
を直接保持する場合の倍のストレージを使用します。この値カテゴリの違いによる異なった振る舞いはどちらにせよ非効率で、固定エクステントspan
がview
だった場合のデメリットよりもひどいものです。
固定エクステントのspan
は正当な理由でデフォルトコンストラクタを持たず、view
にするためにデフォルトコンストラクタを構築するとユーザーが気を付けてチェックしなければならない追加の状態が導入されます。span
の全ての操作に文書化の必要がある事前条件が課されることになり、これはまたすべてのview
にも当てはまっています。
この観点からもやはり、view
コンセプトのデフォルト構築要求は不要であるといえます。
P2328R0 join_view should join all views of ranges
std::ranges::join_view
の制約を緩和して、prvalueのview
ではないrange
を平坦化できるようにする提案。
join_view
はrange
のrange
となっているシーケンスを1つのrange
に平坦化するもので、他のところではflatten
とも呼ばれています。
ここに1つ機能を加えて、要素(内側のrange
)を変換しつつ平坦化するflat_map
というものがあります。そのまま書くと、C++20時点では次のようになるはずです。
template<std::ranges::range R, std::invocable<std::ranges::range_value_t<R>> F> requires std::ranges::range<std::ranges::range_value_t<R>> and std::ranges::range<std::invoke_result_t<F, R>> auto flat_map(R&& r, F&& f) { return r | std::views::transform(f) | std::views::join; }
このようなrange
アダプタのチェーンはほとんどの場合にコンパイルエラーとなります。
現在のjoin_view
が平坦化できるのは次の2つのどちらかです。
- glvalueな
range
のrange
- prvalueな
view
のrange
r | std::views::transform(f)
の結果はf
の結果のrange
によるprvalueなview
となり、f
の結果のrange
がprvalueなview
とならない場合にコンパイルエラーとなります。少し考えてみると、これはかなり一般的なユーズケースであることがわかると思います(f
の結果として範囲を返すとき、std::vector
を使いたくなりませんか?)。
現在のjoin_view
にprvalueな(view
ではない)range
のrange
サポートが欠けていることによってこの問題は発生しています。
Range-v3ライブラリでは、views::cache1
(提案されている名前はviews::cache_latest
)というview
を間に挟むことでこの問題を解決し、views::flat_map
を導入しています。
cache1
は元のrange
のイテレータの間接参照結果をキャッシュとして持っておくことによって、prvalueなrange
のrange
をglvalueなrange
のrange
に変換するものです。これによってjoin_view
はあらゆるケースで平坦化できるようになります。
ただ、cache1
(cache_latest
)にはいくつかの問題があります
- イテレータの
operator*() const
(std::indirectly_readble
コンセプトで要求される)は内部でキャッシュを操作するため、スレッドセーフではない。- 標準ライブラリの
const
メンバ関数はスレッドセーフであることを表明している。
- 標準ライブラリの
cache1
の理解や発見は自明ではない。- なぜそれが必要なのかのヒントはなく、
join_view
の使用を通してその存在の必要性を納得するしかない。
- なぜそれが必要なのかのヒントはなく、
現在のjoin_view
は、prvalueなview
のrange
を処理する際に、内側のprvalueなview
を内部でキャッシュしておくことによって処理しています。この提案では、cache_latest
を導入する代わりに、このキャッシュ機構をprvalueな(view
ではない)range
のrange
に対しても行うことで上記の問題の解決を図ります。
ただし、この場合のキャッシュは伝播しません。すなわち、そのようなキャッシュを保持しているjoin_view
をコピー/ムーブすると、コピー/ムーブ先ではキャッシュは空となります。これによって、join_view
のコピー/ムーブが元のrange
の生成するものに依存しないことが保証されています。また、このようなキャッシュをしている場合のjoin_view
はinput_range
であり、begin()
の呼び出しは1度しか行えません(最初のbegin()
の呼び出し後にrange
として使用不可能となる)。
P2330R0 WG21 2021-02 Virtual Meeting Record of Discussion
2月のWG21本会議における発言記録。
コア言語に関して
- 昨年11月の本会議で採択されたP2238R0にあるコア言語IssueがC++20に対するDefect Report(DR)として扱うことを決定。
- P1787R6の内容をDRとして扱うことを決定(バージョンは指定されていない)。
- P2313R0の内容をDRとして扱うことを決定(バージョンは指定されていない)。
ライブラリ機能に関してはP0533R7 constexpr for <cmath>
and <cstdlib>
(リンクはR6)がリジェクトされた過程が記載されています。
それによれば、精度低下によるエラーが定数評価を妨げる可能性があるという問題提起があり、その解決策について十分に議論が尽くされておらず、このままだと実装が困難となるか実装間で相違が発生する可能性があるという点が懸念され、投票の結果反対および中立が多く出たため、リジェクトされたようです。
P2332R0 Establishing std::hive as replacement name for the proposed std::colony container
提案中のstd::colony
の名前をstd::hive
に変更する提案。
LEWGの議論の過程で、std::colony
という名前に関して何人かのメンバが次のような疑問を抱いているようです
colony
という単語は多くの意味を含んでいるcolony
という名前は馴染みがなく、一般的では無い
色々な名前の候補が上がった結果、hive
(ミツバチの巣)が選ばれたようです。これにはLEWGの多くのメンバとstd::colony
の作者(著者)の方も同意を示しているようです。
colony
(集団・居住地・村など)のお気持ちは
- コンテナそのものがコロニー
- 記憶ブロック(配列)が家
- 要素の記憶域が部屋
- 要素は人
- 人の行き来(要素の挿入・削除)に対して家や部屋に変化はない(記憶域と配列は安定)
hive
のお気持ちは
- コンテナは巣箱
- 1記憶ブロック(配列)が1つの巣板
- 要素の記憶域は6角形のセル
- 要素はミツバチ
hive
ではミツバチがセルに住んでいる訳ではないことから要素の安定性に関しての表現が足りていないとのことですが、LEWGでは名前の意味の単純化のために許容されたようです。
また、std::colony
が力を発揮する用途がイテレーション時に要素の挿入・削除が頻繁に起こるようなケースであり、蜂の巣の出入りの忙しさがこの側面を表現しているとして好まれたようです。
- P0447R11 Introduction of std::colony to the standard library - [C++]WG21月次提案文書を眺める(2020年11月)
- P2332 進行状況
P2333R0 2021 Winter Library Evolution Poll Outcomes
2021年の冬(1月から3月にかけて)に行われた、LEWGの全体投票の結果。
以下の9つの提案が投票にかけられ、どれもLWGに転送されることが可決されています。
- P0288R7 any_invocable
- P2265R0 Renaming any_invocableによって、
move_only_function
に名前が変更されました。
- P2265R0 Renaming any_invocableによって、
- P1642R5 Freestanding Library: Easy [utilities], [ranges], and [iterators]
- P2216R2 std::format improvements
- P2077R2 Heterogeneous erasure overloads for associative containers
- P2136R2 invoke_r
- P1951R0 Default Arguments for pair's Forwarding Constructor
- P2231R0 Add further constexpr support for optional/variant
- P0901R8 Size feedback in operator new
- P1478R6 Byte-wise atomic memcpy
P2334R0 Add support for preprocessing directives elifdef and elifndef
#elif
でマクロの定義の有無で条件分岐する糖衣構文となるプリプロセッシングディレクティブである#elifdef/#elifndef
の提案。
#ifdef/#ifndef
は#if defined(macro_name)/#if !defined(macro_name)
の糖衣構文として随分前から利用可能ですが、#elif defined(macro_name)/#elif !defined(macro_name)
に対応する糖衣構文はありません。
このような構文の一貫性のなさは、一部のユーザーにとっては予測可能ではありません。
#elifdef/#elifndef
を追加し一貫性を改善することで、ユーザビリティの向上を図る提案です。
#ifdef M1 ... #elif defined(M2) ... #endif // ↑が↓こう書ける #ifdef M1 ... #elifdef(M2) ... #endif
この提案はすでにC23に導入されており、C/C++間の互換性確保のためにC++に対しても提案されているものです。
P2338R0 Freestanding Library: Character primitives and the C library
<charconv>
とstd::char_traits
をはじめとするいくつかのヘッダをフリースタンディングライブラリ指定する提案。
C/C++の標準ライブラリにはシステムプログラムにおいて有用な機能が多数存在していますがそれらのライブラリ機能は必ずしもフリースタンディング指定されていないため、コンパイラ拡張などの移植性の乏しい形で利用するか、自分で実装するしかない場合が多いようです。
そのようなライブラリ機能のうち、OSのサポートや動的メモリ確保を必要とせずに実装できるものをフリースタンディングライブラリとして提供することによって、より高レベルにシステムプログラムを記述し、かつそれを移植可能にすることができます。
この提案は、フリースタンディングライブラリをOSや動的なメモリ確保に依存しない標準ライブラリの最大のサブセットとして提供することを目的とした一連の取り組みの一環です。
この提案でフリースタンディング指定を提案されているのは次のものです
<string>
std::char_traits
<charconv>
<cinttypes>
<cstdlib>, cmath
abs()
とstd::abs()
オーバーロード
<cstring>
<cwchar>
<cerrno>, <system_error>
errno
を除く各種エラー定義マクロとstd::errc
この提案は同時にC標準に対しても行われています。
P2339R0 Contract violation handlers
契約プログラミングについて、契約違反を起こしたときに終了するのではなく継続する場合のユースケースについて説明した文書。
C++20でリジェクトされたコントラクト仕様にも、現在議論されているものにも、契約違反が起きた時のデフォルトの対応はstd::terminate()
やstd::abort()
を実行してその場で終了することです。
しかし、契約違反が起きた時でも実行を継続したい場合があり、C++20の仕様には違反継続モードがあり、現在の議論では例外を投げる、return;
するなどが議論されているようですが、どちらも反対意見があるようです。
この文書はC++23の契約プログラミング導入にむけて、契約違反時に実行を継続するユースケースやその利点についてSG21内で共通の理解を得るためのものです。
P2340R0 Clarifying the status of the ‘C headers’
現在非推奨とされているCヘッダを相互運用の目的で使用可能なようにする提案。
ISO規格の文脈での非推奨(deprecated)という言葉は、使用されない・推奨されない・将来削除されうる、などの意味を持ちます。C++が規格化されて以降、Cのヘッダは非推奨という扱いで規定されており、C++のエコシステムとして提供はされているが使用しづらいものとなっていました。
C++におけるCヘッダの主な役割は、C言語との相互運用性およびC言語のABIとリンケージ規則を使用する他のシステムとの相互運用のためにあり、非推奨なのは相互運用を目的としないC++コードでの利用時だけなはずです。この提案は、CヘッダをCおよびその互換システムとの相互運用の目的のために利用することができるように、Cヘッダの非推奨を解除してCのヘッダ群がC++のエコシステムとして提供されることを明確にしようとする提案です。
なお、ここでのCヘッダとは<cxxx>
という形式のC++におけるC互換ヘッダではなく、Cの標準ライブラリヘッダとして定義されている<xxx.h>
の形式のものを指しています。
この提案の後でも、Cコードとして有効である必要がないC++コードでのCヘッダの使用は推奨されません。あくまでCのABIおよびリンケージを利用するシステムとの相互運用性確保のための変更です。
P2400R0 Library Evolution Report
2020年10月27日~2021年2月16日の間の、LEWGの活動記録。
LEWGにおいて議論されている機能の現状について、及びレビューや投票を行った提案のリストなどがあります。
Executor
P0443R14のレビューが完了し、そこで得られたフィードバックに基づいてP0443R15を準備中のようです。投稿され次第、再びレビューが行われる予定です。
コルーチンのライブラリサポート
P2168R1(std::generator
)の改訂版が近々提出される予定で、そのレビューはすぐに行われる予定です。
しかし、他の提案は一度のレビューの後改訂されておらず、std::generator
以外のコルーチン関連のライブラリサポートの議論は止まっているようです(ただし、Executorに依存しているために止まっているものがある可能性があります)。
Networking TS
Networking Study Groupで議論が続いており、まだLEWGに提出されていません。これはExecutorに依存していますが、大きな機能であるために並行して作業が可能なはずです。
2021年春頃までにLEWGでのレビューに進めない場合、C++23に間に合わなくなる可能性があります。
標準ライブラリのモジュール化
2020年春以降、関連した活動が見られないようです。このまま議論もされなければ、C++23には間に合いません。
ranges
P2214R0をレビューし、この提案の方向性でのRangeライブラリの拡張をLEWGは支持しています。
P2210R0(std::ranges::split_view
の改善)はLEWGにおける最終レビューを通過し、LWGに転送するための電子投票にかけられる予定です。前回の電子投票の期限に間に合わなかったためまだ投票は行われていませんが、2021年春頃には投票が開始される予定です。
ranges関連の提案をよく書いている著者の方が協力的かつ活発なためranges関連のレビューはスムーズに進行しており、提案は迅速に処理されているようです。
format
P2216R2(std::foramt
の改善)はLEWGにおける最終レビューを通過しており、2021年1月に電子投票にかけられました。この提案にはC++20に対する破壊的な変更が含まれていますが、既存実装が無いために影響は無いと判断されました。
P2093R2(std::print
)はまだLEWGで議論の真っ最中ですが、著者の方の応答性が高いために作業は順調に進行しているようです。早ければ2021年春頃にLWGに転送される可能性があるようです。
Text and Unicode
P1885R3がLEWGに提出されており、メーリングリストレビューおよびテレカンレビューを完了したようです。改善の必要があったため、改訂待ちをしています。
フリースタンディング
P1462R5(<utility>, <ranges>, <iterator>
のフリースタンディングサポート)のLEWGでの最終レビューが完了し、2021年1月にLWGに転送するための最後の電子投票にかけられました。