namespace std {
template<class In>
concept indirectly_readable = /*see below*/;
}
概要
indirectly_readable
は、任意の型In
が間接参照演算子(operator*
)によって値を読み取り(入力)可能であることを表すコンセプトである。
イテレータ型に限らず、ポインタ型、スマートポインタ型などがこのコンセプトのモデルとなることができる。
要件
まず、説明専用コンセプトindirectly-readable-impl
を以下のように定義する。
template<class In>
concept indirectly-readable-impl =
requires(const In in) {
typename iter_value_t<In>;
typename iter_reference_t<In>;
typename iter_rvalue_reference_t<In>;
{ *in } -> same_as<iter_reference_t<In>>;
{ ranges::iter_move(in) } -> same_as<iter_rvalue_reference_t<In>>;
} &&
common_reference_with<iter_reference_t<In>&&, iter_value_t<In>&> &&
common_reference_with<iter_reference_t<In>&&, iter_rvalue_reference_t<In>&&> &&
common_reference_with<iter_rvalue_reference_t<In>&&, const iter_value_t<In>&>;
indirectly_readable
は以下のように定義される。
template<class In>
concept indirectly_readable =
indirectly-readable-impl<remove_cvref_t<In>>;
モデル
型I
のオブジェクトi
について、*i
が等しさを保持する場合に限って型I
はindirectly_readable
のモデルである。
例
#include <iostream>
#include <concepts>
#include <memory>
#include <vector>
#include <optional>
template<typename T>
requires std::indirectly_readable<T>
void f(const char* name) {
std::cout << name << " is indirectly readable" << std::endl;
}
template<typename T>
void f(const char* name) {
std::cout << name << " is not indirectly readable" << std::endl;
}
int main() {
f<int*>("int*");
f<std::unique_ptr<int>>("std::unique_ptr<int>");
f<std::vector<int>::iterator>("std::vector<int>::iterator");
f<std::istream_iterator<double>>("std::istream_iterator<double>");
std::cout << "\n";
f<std::optional<int>>("std::optional<int>");
}
出力
int* is indirectly readable
std::unique_ptr<int> is indirectly readable
std::vector<int>::iterator is indirectly readable
std::istream_iterator<double> is indirectly readable
std::optional<int> is not indirectly readable
バージョン
言語
- C++20
処理系
- Clang: ??
- GCC: 10.1 ✅
- Visual C++: 2019 Update 6 ✅