yohhoyの日記

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

C++

Read-Copy Update @ C++26

C++2c(C++26)標準ライブラリに追加される<rcu>ヘッダについて。Read copy updateの略。 // C++2c #include <atomic> #include <mutex> // scoped_lock #include <rcu> struct Data { int m1; /*...*/ }; std::atomic<Data*> data_; // new確保された初期値が別途設定される前提 void multiple</data*></rcu></mutex></atomic></rcu>…

std::submdspan関数

C++2c(C++26)標準ライブラリに追加される多次元部分ビューstd::submdspanについて。 // <mdspan>ヘッダ namespace std { template< class T, class E, class L, class A, class... SliceSpecifiers> constexpr auto submdspan( const mdspan<T, E, L, A>& src, SliceSpecifiers..</t,></mdspan>…

GCC -pedanticオプション

GCCコンパイラの -pedantic オプションについてメモ。 pedantic 形容詞 〈侮蔑的〉〔文法・学問的なことなどについて〕重要でない事にこだわり過ぎる、学者ぶった、知識をひけらかす、衒学的な https://eow.alc.co.jp/search?q=pedantic GCC 2.95.3マニュア…

関数戻り値の破棄を明示

プログラミング言語C++において、nodiscard属性が指定された関数に対し意図的な戻り値破棄を明示する方法。まとめ: C++23現在は、方式(3) std::ignoreへの関数戻り値代入が実践的か。*1 C++2c(C++26)以降は、方式(4) プレースホルダ識別子_(アンダースコア…

std::mdspan AccessorPolicy応用例

C++23標準ライブラリの多次元ビューstd::mdspan(→id:yohhoy:20230303)における、第4テンプレートパラメータAcssesorPolicyを用いた要素アクセスカスタマイズの具体事例。C++2c(C++26)標準ライブラリ採用が決定している線形代数基本アルゴリズム <linalg> ヘッダで</linalg>…

std::views::filter適用後の値書換えには要注意

C++

C++標準ライブラリ提供レンジアダプタstd::views::filter適用後の要素に対する変更操作には十分留意すること。変更操作により要素がフィルタ条件を満たさなくなる場合、C++ライブラリ仕様上は未定義動作(undefined behavior)を引き起こす。この問題は遅延評…

Living Dead/Zombie in C++ Standard

C++

プログラミング言語C++標準規格の索引(Index)に紛れ込むリビングデッド。*1 brains names that want to eat your, [zombie.names]living dead name of, [zombie.names] https://github.com/cplusplus/draft/commit/e844e0f45550eb0bf11ea262e4abd8a5403f47d4…

飽和演算サポート @ C++26

C++2c(C++26)標準ライブラリに追加される飽和演算(saturation arithmetic)サポートについてメモ。 // C++2c <numeric>ヘッダ namespace std { // T,U = 符号付き整数型 or 符号無し整数型 template<class T> constexpr T add_sat(T x, T y) noexcept; template<class T> constexpr T sub</class></class></numeric>…

異種クラス同名メンバ関数の個別オーバーライド

C++

プログラミング言語C++において、異なる基底クラスに属する同名メンバ関数*1を個別にオーバーライドする方法。 // 同名メンバ関数をカスタマイズポイントとして提供する // 互いに無関係なインタフェースクラス struct Interface1 { virtual void process() …

NEO assertマクロ

プログラミング言語C/C++の次期標準規格C2x(C23)およびC++2c(C++26)では、アサーションマクロassertの改善が行われる。 #include <assert.h> // C/C++ #include <cassert> // C++のみ int is_valid(int); assert( "42 shall be vaild", is_valid(42) ); // NG: C17/C++20現在 //</cassert></assert.h>…

signal関数プロトタイプ宣言

C C++

C++17以降のC++標準ライブラリ仕様では、signal関数のプロトタイプ宣言が読みやすく書き直されている。 C++17仕様 C++標準ライブラリ仕様としてプロトタイプ宣言が行われている。C++17 21.10.3より宣言を引用: Header <csignal> synopsis namespace std { // 21.10.4</csignal>…

タグ型の実装イディオム

C++

C++標準ライブラリで使われるタグ型(tag type)とタグ値の実装イディオム。デフォルトコンストラクタへのexplicit指定は、{}によるタグ型(mytag_t)デフォルト構築を禁止するため。 struct mytag_t { explicit mytag_t() = default; }; inline constexpr mytag…

式のコンパイル時評価判定

C++

C++20言語機能を利用した、ある式がコンパイル時に評価可能かを判定するメタ関数的なもの。id:yohhoy:20190528 の別解。本記事の内容はStackOverflowで見つけた質問と回答に基づく。 // C++20以降 template<class Lambda, int = (Lambda{}(), 0)> constexpr bool is_constexpr(Lambda) { return tr</class>…

関数名/メンバ関数名とアドレス演算子

C++

プログラミング言語C++において、通常関数名やstaticメンバ関数名から関数ポインタ型へは暗黙変換が行われるが、メンバ関数名からメンバ関数ポインタ型への変換はアドレス演算子&利用が必須。 void f0(); struct S { static void f1(); void mf(); }; // (通…

std::destructibleコンセプト

C++

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

std::expectedと強い例外安全性

C++2b(C++23)標準ライブラリに追加されるstd::expected<T, E>の例外安全性についてメモ。正常型T/エラー型Eを値(value)として取り扱いつつ「強い例外安全性(Strong exception safety)」を満たすために、テンプレートパラメータに一定の制約が課される。 ムーブ/</t,>…

空っぽの構造体

メンバ変数を1個ももたない空(empty)の構造体は、C++言語ではwell-definedとされるが、C言語ではill-formedとなる。 // C++: OK / C: NG struct S { }; GCCでは独自拡張として空の構造体を許容するが、標準C++とは異なり構造体サイズが0となることに注意。 /…

std::mdspan×空間充填曲線

C++2b(C++23)標準ライブラリの多次元ビューstd::mdspanクラステンプレート(→id:yohhoy:20230303)は、第3テンプレートパラメータLayoutPolicyを介して任意のメモリレイアウトをサポートする。*1C++2b標準ライブラリは、多次元配列表現としてメジャーな行優…

0次元std::mdspan

C++2b(C++23)標準ライブラリの多次元ビューstd::mdspanクラステンプレート(→id:yohhoy:20230303)では、0次元(rank-0)ビューをサポートする。意味論上は “単一変数へのポインタ” に相当する。(´-`).。oO(使うことあるか?) 2024-02-01追記:C++2c(C++26)…

std::mdspanコンストラクタとCTAD

C++2b(C++23)標準ライブラリに追加される多次元ビューstd::mdspanクラステンプレート(→id:yohhoy:20230303)の、コンストラクタと推論ガイド(deduction guide)による実引数クラステンプレート推論(CTAD; Class Template Argument Deduction)のあれこれ。mds…

std::mdspan

C++2b(C++23)標準ライブラリに追加される多次元ビューstd::mdspanについて。multidimensional spanの略。 // <mdspan>ヘッダ namespace std { template< class ElementType, class Extents, class LayoutPolicy = layout_right, class AccessorPolicy = default_acce</mdspan>…

ヌル終端文字列のstd::hash計算

C++

C++標準ライブラリのハッシュ計算ファンクタstd::hashを用いてヌル終端文字列のハッシュ計算を行う場合、ポインタ型に対するstd::hash<const char*>特殊化ではなくstd::hash<std::string_view>特殊化を用いる。*1下記コードにあるh0では、“文字列” からではなくアドレス値からハッシュ計算さ</std::string_view></const>…

static_assert(false, "was wrong");

C++

プログラミング言語C++におけるconstexpr if文とstatic_assert宣言の組合せに関するメモ。2023年2月会合にてstatic_assert(false)を許容するP2593R1がCWG 2518へと統合され*1、C++言語仕様に対するDefect Reportとして遡及適用される。*2CWG 2518適用前のC++…

std::monostateのハッシュ値

C++標準ライブラリの直和データ型std::variant<...>と組み合わせて空の状態を表すstd::monostateオブジェクトでは、std::hashによるハッシュ計算がサポートされる。*1各C++処理系で算出されるハッシュ値の一覧(括弧内は併記コメント/定数名): GCC: -7777…

TemplateParam = void

C++ライブラリのクラステンプレート設計で見られる、型テンプレートパラメータへのvoidデフォルト指定に関するメモ。 template<class T = void> class SomeClass; C++2b(C++23)標準ライブラリ時点では、下記パターンでの用法が存在する。 デフォルトvoid型:std::enable_if(</class>…

変数型のコンパイル時判定

プログラミング言語C++において、コンパイル時にある変数の宣言型を判定する方法あれこれ。 // 型名T と 変数名val // C++11以降 #include <type_traits> static_assert(std::is_same<T, decltype(val)>::value, ""); // C++17以降 #include <type_traits> static_assert(std::is_same_v<T, decltype(val)>); // C++20以降 #</t,></type_traits></t,></type_traits>…

非型テンプレートパラメータでのオーバーロード解決は行われない

C++

関数テンプレートの非型テンプレートパラメータ(non-type template parameter)において、通常のC++オーバーロード解決規則は適用されない。沼に近よるべからず ('ω'乂) template <bool N> void f() {} // #1 template <int N> void f() {} // #2 f<0>(); // NG: オーバーロ</int></bool>…

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

C++

C++20標準ライブラリ提供レンジアダプタstd::views::splitとstd::views::lazy_splitの比較。*1まとめ: 入力レンジを区切りパターン(単一要素またはレンジ)を用いて分割し、「部分レンジ(subrange)のレンジ」へと変換するレンジアダプタ(range adaptor)。*…

オーバーロード関数とテンプレート引数推論

C++

プログラミング言語C++において、オーバーロードされた関数群をテンプレートパラメータへ引き渡す方法。テンプレート引数の関数型を一意に推論できないため、ジェネリックラムダ式でラップする必要がある。テンプレート引数Fはラムダ式に対応する固有のクロ…

R.I.P. "= {0}"

プログラミング言語Cの次期C2x(C23)言語仕様では、空のブレース{}を用いた配列・構造体の初期化が許容される。C++では当初からOK。 typedef struct S { int m1, m2; } S; // C17:ill-formed / C2x:OK / C++:OK int arr0[10] = {}; S obj0 = {}; // C:OK / C+…