namespace std {
template<indirectly_readable I, indirectly_regular_unary_invocable<I> Proj>
struct projected {
using value_type = remove_cvref_t<indirect_result_t<Proj&, I>>;
indirect_result_t<Proj&, I> operator*() const; // 宣言のみ
};
// incrementable_traitsにアダプトする
template<weakly_incrementable I, class Proj>
struct incrementable_traits<projected<I, Proj>> {
using difference_type = iter_difference_t<I>;
};
}
概要
間接参照可能な型I
に任意の射影操作Proj
を適用した結果を表すindirectly_readable
のモデルとなる型を生成する。
これは射影操作を受け取るコンセプトやアルゴリズムを制約するために使用するものであり、評価される文脈で使用可能ではない。主に、射影操作の結果に対してイテレータ関連のコンセプトを適用する場合に使用する(射影の結果を再びindirectly_readable
な型に写す事で、一部のイテレータに対するコンセプトを使いまわす事が出来る)。
例
#include <iterator>
#include <vector>
int main() {
using vec_iterator = std::vector<int>::iterator;
using vecitr_proj = std::projected<vec_iterator, std::identity>;
static_assert(std::indirectly_readable<vecitr_proj>);
static_assert(std::same_as<vecitr_proj::value_type , int>);
static_assert(std::same_as<std::iter_difference_t<vecitr_proj> , std::ptrdiff_t>);
static_assert(std::same_as<std::iter_value_t<vecitr_proj> , int>);
static_assert(std::same_as<std::iter_reference_t<vecitr_proj> , int&>);
static_assert(std::same_as<std::iter_rvalue_reference_t<vecitr_proj>, int&&>);
static_assert(std::same_as<std::iter_common_reference_t<vecitr_proj>, int&>);
//別の射影でプロジェクション
using vecitr_proj2 = std::projected<vec_iterator, decltype([](int) -> double { return 0.0;})>;
static_assert(std::indirectly_readable<vecitr_proj2>);
static_assert(std::same_as<vecitr_proj2::value_type , double>);
static_assert(std::same_as<std::iter_difference_t<vecitr_proj2> , std::ptrdiff_t>);
static_assert(std::same_as<std::iter_value_t<vecitr_proj2> , double>);
static_assert(std::same_as<std::iter_reference_t<vecitr_proj2> , double>);
static_assert(std::same_as<std::iter_rvalue_reference_t<vecitr_proj2>, double>);
static_assert(std::same_as<std::iter_common_reference_t<vecitr_proj2>, double>);
}
出力
バージョン
言語
- C++20
処理系
- Clang: ??
- GCC: 10.1 ✅
- Visual C++: 2019 Update 6 ✅