namespace std {
template<indirectly_readable It>
using iter_const_reference_t = common_reference_t<const iter_value_t<It>&&, iter_reference_t<It>>;
}
概要
任意のイテレータ型Itから、そのイテレータの要素へのconst参照型を取得する。
型の決定
iter_value_t<It>が非参照型でありiter_reference_t<It>から修飾を除いた型であるとすると、iter_reference_t<It>に対してiter_const_reference_t<It>は基本的には次のようになる(Tを任意の修飾なしの型とする)
iter_reference_t<It> |
iter_const_reference_t<It> |
|---|---|
T& |
const T& |
T&& |
const T&& |
const T& |
const T& |
const T&& |
const T&& |
T |
T |
const T |
T |
iter_value_t<It>に対してiter_reference_t<It>が修飾以外も異なる型となる場合や、Itに対してiterator_traitsの特殊化が存在する場合、const iter_value_t<It>&&とiter_reference_t<It>についてcommon_referenceが特殊化されている場合などはこれと異なる結果となりうる。標準ライブラリにあるそのようなイテレータ型を持つものについて一部例を示すと、次のようになる
Itの取得元の範囲 |
iter_value_t<It> |
iter_reference_t<It> |
iter_const_reference_t<It> |
|---|---|---|---|
std::vector<bool> |
bool |
std::vector<bool>::reference |
bool |
const std::vector<bool> |
bool |
bool |
bool |
views::zip |
std::tuple<T, U> |
std::tuple<T&, U&> |
std::tuple<const T&, const D&> |
views::enumerate |
std::tuple<D, T> |
std::tuple<D, T&> |
std::tuple<D, const T&> |
表中のT, Uはそれそれのviewに入力された範囲の値型、Dはviews::enumerateの入力範囲のiter_difference_tとする。
例
#include <iterator>
#include <tuple>
// indirectly_readableとなる最低限の型
// Rが参照型、Vが値型となる
template<typename R, typename V>
struct test_indirectly_readable {
using value_type = V;
using difference = std::ptrdiff_t;
auto operator*() const -> R;
};
int main() {
static_assert(std::same_as<std::iter_const_reference_t<test_indirectly_readable<int& , int>>, const int&>);
static_assert(std::same_as<std::iter_const_reference_t<test_indirectly_readable<int&& , int>>, const int&&>);
static_assert(std::same_as<std::iter_const_reference_t<test_indirectly_readable<const int& , int>>, const int&>);
static_assert(std::same_as<std::iter_const_reference_t<test_indirectly_readable<const int&&, int>>, const int&&>);
static_assert(std::same_as<std::iter_const_reference_t<test_indirectly_readable<int , int>>, int>);
static_assert(std::same_as<std::iter_const_reference_t<test_indirectly_readable<const int , int>>, int>);
static_assert(std::same_as<std::iter_const_reference_t<test_indirectly_readable<std::tuple<int, double> , std::tuple<int, double>>>, std::tuple<int, double>>);
static_assert(std::same_as<std::iter_const_reference_t<test_indirectly_readable<std::tuple<int&, double&>, std::tuple<int, double>>>, std::tuple<const int&, const double&>>);
static_assert(std::same_as<std::iter_const_reference_t<test_indirectly_readable<std::tuple<int, double>& , std::tuple<int, double>>>, const std::tuple<int, double>&>);
}
出力
バージョン
言語
- C++23
処理系
- Clang: ??
- GCC: 13.1 ✅
- Visual C++: 2022 Update 6 ✅