C++23標準ライブラリの多次元ビューstd::mdspan
(→id:yohhoy:20230303)における、第4テンプレートパラメータAcssesorPolicy
を用いた要素アクセスカスタマイズの具体事例。
C++2c(C++26)標準ライブラリ採用が決定している線形代数基本アルゴリズム <linalg> ヘッダでは、mdspan
参照先のメモリを書換えずに各要素のスケーリング(std::linalg::scaled
)や複素共役(std::linalg::conjugated
)変換を行うビューを提供する。適用後の多次元ビュー要素は読み取り専用となる。
#include <mdspan> #include <linalg> // C++2c(C++26) using Vec = std::mdspan<int, std::dextent<size_t, 1>>; int arr[] = {1, 2, 3}; Vec vec1{ arr }; assert(vec1[0] == 1); // 要素アクセス vec1[i] はint&型を返す // &(vec1[i]) == &(arr[i]) // 全要素を2倍した1次元ビュー auto vec2 = std::linalg::scaled(2, vec1); assert(vec2[0] == 2 && arr[0] == 1); // 要素アクセス vec2[i] はint型を返すため // 要素書き換え vec2[0] = 42; はill-formed
提案文書P1673R13 Wordingより一部引用(クラス宣言は簡略化)。
1 The class template
scaled_accessor
is anmdspan
accessor policy which upon access produces scaled elements. reference. It is part of the implementation ofscaled
[linalg.scaled.scaled].template<class ScalingFactor, class NestedAccessor> class scaled_accessor { public: using element_type = add_const_t< decltype(declval<ScalingFactor>() * declval<NestedAccessor::element_type>())>; using reference = remove_const_t<element_type>; using data_handle_type = NestedAccessor::data_handle_type; using offset_policy = /*...*/; constexpr scaled_accessor(const ScalingFactor& s, const NestedAccessor& a); constexpr reference access(data_handle_type p, size_t i) const; // ... };
1 The
scaled
function template takes a scaling factoralpha
and anmdspan
x
, and returns a new read-onlymdspan
with the same domain asx
, that represents the elementwise product ofalpha
with each element ofx
.template<class ScalingFactor, class ElementType, class Extents, class Layout, class Accessor> constexpr auto scaled( ScalingFactor alpha, mdspan<ElementType, Extents, Layout, Accessor> x);2 Let
SA
bescaled_accessor<ScalingFactor, Accessor>
3 Returns:mdspan<typename SA::element_type, Extents, Layout, SA>( x.data_handle(), x.mapping(), SA(alpha, x.accessor()))
メモ:<linalg> ヘッダではこのほかに行列転置(std::linalg::transposed
)や複素共役転置(std::linalg::conjugate_transposed
)変換を行うビューも提供する。行列転置はmdspan
の第3テンプレートパラメータLayoutPolicy
を利用して実現される。
関連URL