yohhoyの日記

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

C++20, コンセプト の検索結果:

std::destructibleコンセプト

C++

C++20標準ライブラリstd::destructible<T>コンセプトに関するメモ。ある型Tが「例外送出なしにデストラクト可能」と制約(constraint)するコンセプト。デストラクタは既定で暗黙のnothrow指定が行われるため*1、明示的にnothrow(false)指定を行わない限りあらゆるオブジェクト型が満たすコンセプトとなる。*2std::destructibleコンセプトは、標準ヘッダ <concepts> 提供のオブジェクト関連コンセプトにより直接/間接的…

std::views::splitとstd::views::lazy_split

C++

C++20標準ライブラリ提供レンジアダプタstd::views::splitとstd::views::lazy_splitの比較。*1まとめ: 入力レンジを区切りパターン(単一要素またはレンジ)を用いて分割し、「部分レンジ(subrange)のレンジ」へと変換するレンジアダプタ(range adaptor)。*2 大半のユースケースでsplitを用いればよい。 使い勝手を重視:部分レンジ(std::ranges::subrange)への分割処理を遅延評価する。*3 入力レンジ…

std::generator<R>

…わかった気分になれるC++20コルーチン - yohhoyの日記 コルーチン×ラムダ式キャプチャ=鼻から悪魔 - yohhoyの日記 *1:std::ranges::fold_left アルゴリズムは P2322R6 にてC++2b標準ライブラリへ追加予定となっている。 *2:std::generator<R>::promise_type 型の初期サスペンドポイント(initial_suspend)は suspend_always 型を返す。 *3:C++20 <corout…

C++オブジェクト基本操作:Copyable/Movable/Swappable

C++

…20190903)。C++20 18.4.9/p4, 18.6/p1より一部引用。 template<class T> concept swappable = requires(T& a, T& b) { ranges::swap(a, b); }; // (snip) [Note: The semantics of the swappable and swappable_with concepts are fully defined by the ranges::swap …

コンセプト制約式の構成:包摂関係 vs. コンパイル時間

C++

C++20コンセプトでは制約式(constraint-expression)を&&(conjunction)/||(disjunction)で組み合わせることで複雑な制約式を表現できる。一方で制約式が多数の原始制約(atomic constraint)から構成されるケースでは、包摂関係(subsumption relation)判定のための正規化プロセスが複雑になりコンパイル時間に悪影響を及ぼす。例えばコンセプトX, Y, Zからなるコンセプトの定義方法として、下記2種類が考…

std::views::commonレンジアダプタの制約

C++20 RangeからC++17互換イテレータペアへの変換にはstd::views::commonレンジアダプタ(range adaptor)を利用する。ただしstd::ranges::basic_istream_viewなどムーブのみ/コピー不可なイテレータからなる一部Rangeは変換できない。*1 #include <sstream> #include <ranges> #include <vector> auto ints = std::istringstream{…

コンセプト定義への属性指定

C++

C++20言語仕様では、コンセプト定義に対して属性(attribute)を指定できない。 template <typename T> [[deprecated("concept")]] // NG: ill-formed concept C = /*...*/; // OK: 変数テンプレート template <typename T> [[deprecated("variable")]] T var = /*...*/; // OK: 関数テンプレート template <…

クラステンプレート特殊化型判定

C++

…lue ); // C++20: is_complexコンセプト #include <concepts> #include <complex> template <typename T> concept is_complex = requires (T t) { { std::complex{std::move(t)} } -> std::same_as<T>; // ムーブのみ可能な型を考慮してrvalueへキャスト // コピー可能な型では単にt(lvalue)記述でもよ…

可変長コンセプト×畳み込み式: The glass is half full or half empty?

C++

C++20コンセプトと論理演算子(&&, ||)による畳み込み式(fold expression)の関係について。本記事の内容はStackOverflowで見つけた質問と回答に基づく。まとめ:&&と||による畳み込み式を用いた制約式(constraint-expression)は機能するものの、コンセプト間の包摂関係(subsumption relation)は期待通りに成り立たない。2023-10-10追記:C++2c(C++26)に向けた提案P2963にて、&&と||畳み…

requires式中でのコンセプト制約表現には要注意

C++20 requires式(requires-expression) において、コンセプトや条件式を用いた制約(constraints)表現には注意が必要。 2022-05-08追記:gcc(g++) 12.1から警告 -Wmissing-requires が追加され、本記事で言及しているrequiresキーワード指定忘れの可能性を検知できる。本警告は既定で有効化される。*1下記コードのように式std::signed_integral<decltype(N)>やN == …

RangeとViewとconst修飾

C++

C++20 RangesライブラリのRangeとViewとconst修飾の関係についてメモ。まとめ: 対象Rangeのconst修飾(要素の変更可否)と、Viewのconst修飾(const-iterableの可否)は異なる概念である。 C++20標準ライブラリ提供の一部Rangeアダプタでは、const修飾によりViewとして機能しなくなるものがある。 具体例:std::views::filter, std::views::drop_while Viewを受け取るパラメータ…

制約式std::bool_constant<cond>::value

C++

C++20 制約式(constraint-expression)でテンプレートパラメータに依存する定数条件式condを表現する場合、非定数式に起因するハードエラーを防ぐためstd::bool_constant<cond>::valueと記述する必要がある。 #include <type_traits> struct X { // X::valueは非定数式 static inline int value = 42; }; struct Y { // Y::valueは定数式 …

std::is_convertible vs. std::convertible_to

C++

… NG: 明示変換 C++20(N4861) 18.4.4/p1, 20.15.6/p5より引用(下線部は強調)。 Given types From and To and an expression E such that decltype((E)) is add_rvalue_reference_t<From>, convertible_to<From, To> requires E to be both implicitly and explicitly converti…

非staticデータメンバを判定する制約式

C++

C++20 requires式(requires-expression)の単純な利用では非static/staticメンバを区別できない。requires式の本体部は評価されない(unevaluated)ため、通常コードとは異なる規則が適用されることに注意。 // staticメンバmを持つ型X struct X { static const int m = 1; }; // (非static)メンバmを持つ型Y struct Y { int m = 2; }; // sta…

requires制約とテンプレート特殊化の関係

C++

C++20コンセプトで導入されたrequires節と、テンプレート特殊化の組み合わせには注意が必要。例えば制約付きプライマリテンプレート(#1)に対してdouble型で明示的特殊化(#2)しようとしても、下記記述コードでは#2定義でill-formedになる。これは#1のrequires節によりT=doubleのときプライマリテンプレート不在とみなされるため。 #include <concepts> // #1 プライマリテンプレート(?) template<typename…

コンセプトのパラメータ置換失敗はハードエラーではない

C++2a(C++20)コンセプトにおける原始制約(atomic constraint)では、パラメータ置換(parameter mapping)の失敗はハードエラー(ill-formed)を引き起こさず、その制約式を満たさない(not satisfied)と解釈される。C++17現在はstd::void_tやstd::conjunctionを駆使した難解なテンプレートメタプログラミング技法が要求されるが、C++2aでは単純な制約式記述によるコンセプト定義により代替される。は…

コンセプトと短絡評価

C++2a(C++20)コンセプトの制約式(constraint-expression)では、論理演算&&, ||は短絡評価される。*1C++17現在のテンプレートメタプログラミングではstd::conjunction, std::disjunctionメタ関数を必要とするが、C++2aコンセプト導入により自然な制約記述が可能となる。 T型が「std::atomic<T>が常にロックフリー(lock free)か否か」を判定するメタ関数は、std::conjunctionメタ…

複合要件とsame_as/convertible_toコンセプト

C++2a(C++20)コンセプト requires式(requires-expression) に記述する 複合要件(compound-requirement) では「ある式の評価結果が特定コンセプトを満たすこと」を制約するが、このとき標準コンセプトstd::same_as/std::convertible_toを適切に使い分ける必要がある。特に “データメンバ型の制約” には注意すること。下記コードのコンセプトC0では式t.dataがint型へと変換可能(converti…

C++コンセプトとド・モルガンの法則

C++2a(C++20)コンセプトでは制約式(constraint-expression)に論理積(&&)/論理和(||)/論理否定(!)を表現できるが、制約式を用いたオーバーロード解決では通常の論理演算で期待される ド・モルガンの法則(De Morgan's laws) は適用されない。*1超要約:否定演算!を使ったコンセプトには要注意! // C++2a #include <concepts> // integral, same_asコンセプト template <typ…

requires式から利用可能な宣言

C++2a(C++20) コンセプト requires式(requires-expression) では、同式を包含するコンテキストのあらゆる宣言を利用できる。下記コードのrequires式からは関数テンプレートの仮引数xを参照している。requires式の本体(requirement-body)は評価されず(unevaluated)、型情報(型T)のみを利用している。 #include <iostream> #include <string> using namespace…

イテレータに->演算子オーバーロードは必要?

…とめ: C++2a(C++20) input_iteratorコンセプトではイテレータ型にoperator*オーバーロードのみ要求する。operator->オーバーロードは要求されない。 C++17以前の InputIterator 要件では、イテレータ型に対してoperator*とoperator->オーバーロードの両方を要求する。 N4835(C++2a WD) Cpp17InputIterator要件はoperator->オーバーロードを要求するが、input_iter…

same_asコンセプトとSymmetric Subsumption Idiom

C++2a(C++20)ライブラリ提供の標準コンセプトstd::same_as、およびコンセプト定義における対称包摂イディオム(Symmetric Subsumption Idiom)についてメモ。制約式std::same_as<X, Y>と制約式std::same_as<Y, X>は対称関係、つまり互いに一方が他方を包摂する(subsume)関係にある。これによりコンセプトへのテンプレートパラメータ指定順が一致していなくとも、制約式を用いた関数オーバーロード解決の半順序関係…

コンセプト制約式の包摂関係とオーバーロード解決

C++2a(C++20)で導入されるコンセプト(concept)に関して、制約式(constraint-expression)間の包摂(subsume)ルールに基づくオーバーロード解決のメモ。本記事の内容はStackOverflowで見つけた質問と回答に基づく。要約:制約式の包摂関係(subsumption relation)判定では、制約を構成するトークン列が同じというだけではダメで、C++ソースコード上での記述位置(=構文木におけるノード)の同一性が考慮される。こんなん分…

C++標準コンセプトの名前付けガイドライン

C++2a(C++20)標準ライブラリに導入される コンセプト(concept) の名前付けガイドラインについて。2019年Cologne会合にて (PDF)P1754R1 が採択され、Ranges TS提案当初から PascalCase 形式で検討されていた命名規則から snake_case 形式へと変更された。これにより従来C++標準ライブラリとの一貫性は向上したが、その名前のみからはコンセプトなのかクラスやメタ関数*1なのかを判別しづらくなっている。*2提案文書P185…

定数式を要求するコンセプト

C++2a(C++20) Conceptを利用した「ある式が定数式であること」を要求する制約式の定義。型パラメータTに対して「T::size()がコンパイル時に評価されること」を要求するコンセプトHasConstantSizeの定義例。requires式(requires-expression)中の typename type-name; 構文(type-requirement)は、type-name が有効な型であることを表明する。例示コードのように、クラステンプレート特殊…

Customization Point Object

C++2a(C++20)標準ライブラリに導入される Customization Point Object についてメモ。*1まとめ: Customization Point == ユーザ定義型に対して事前定義した動作カスタマイズ可能点。具体的な処理実装ソースコードから呼び出される名前。 2021-06-29追記:C++20標準ライブラリのCPOには Customization Point を規定しないものもある。これらはそのCPO名によって動作カスタマイズが行えない点を除いて…

C++ Conceptsの短縮構文(P1141R2)

次期C++2a(C++20)標準規格に向けて採択された、コンセプト(concept)関連の短縮構文についてメモ。C++コンセプト概略ついては id:yohhoy:20170904 を参照のこと。本記事の内容は P1141R2 Yet another approach for constrained declarations に基づく。要約: autoキーワードによる関数テンプレート定義が可能。“template-less Function Template” 現行autoキー…

C++ Concepts(P0734R0)

次期C++2a(C++20)標準規格に向けて採択された コンセプト(concept) についてメモ。*1本記事の内容は(PDF)P0734R0 Wording Paper, C++ extensions for Conceptsに基づく。要約: 新しいキーワード:concept, requires 新しい構文:コンセプト定義, requires式, requires節 コンセプト(concept) == テンプレートパラメータに対する制約(constraint) コンセプト(…

関数パラメータ型としてのauto?

…1追記:C++2a(C++20)言語仕様に向けて、abbreviated function template 構文を含むP1141R2が採択された。同提案は関数テンプレートへのコンセプト制約指定が主目的だが、同構文の自然な拡張(コンセプト制約の省略形)として導入される。id:yohhoy:20190111 参照。2017-09-02追記:発行済み ISO/IEC TS 19217:2015(Concepts TS) には同仕様が含まれるが、C++2aに向けたP0696R0にて…

synchronic同期プリミティブ

…2追記:C++2a(C++20)に向けて提案文書 P1135R6 が採択され、atomic変数std::atomic<T>に wait / notify_one / notify_all 操作が追加される。ループ構造と組み合わせることで、N4195 が目指していた効率的な通知/待機機構を実装できる。std::synchronic<T>クラステンプレートは、スレッド間同期オブジェクトの待機処理を効率的に実装するための低レイヤ同期プリミティブ。atomic変数(std::atom…