最終更新日時(UTC):
が更新

履歴 編集

concept
<iterator>

std::indirectly_unary_invocable/indirectly_regular_unary_invocable(C++20)

namespace std {
  template<class F, class I>
  concept indirectly_unary_invocable =
    indirectly_readable<I> &&
    copy_constructible<F> &&
    invocable<F&, iter_value_t<I>&> &&
    invocable<F&, iter_reference_t<I>> &&
    invocable<F&, iter_common_reference_t<I>> &&
    common_reference_with<
      invoke_result_t<F&, iter_value_t<I>&>,
      invoke_result_t<F&, iter_reference_t<I>>>;

  template<class F, class I>
  concept indirectly_regular_unary_invocable =
    indirectly_readable<I> &&
    copy_constructible<F> &&
    regular_invocable<F&, iter_value_t<I>&> &&
    regular_invocable<F&, iter_reference_t<I>> &&
    regular_invocable<F&, iter_common_reference_t<I>> &&
    common_reference_with<
      invoke_result_t<F&, iter_value_t<I>&>,
      invoke_result_t<F&, iter_reference_t<I>>>;
}

概要

indirectly_unary_invocable及びindirectly_regular_unary_invocableは、間接参照可能な型I(例えばイテレータ型)の参照先の型によって、Fが関数呼び出し可能であることを表すコンセプトである。

単純には、型I, Fのオブジェクトをそれぞれi, fとするとf(*i)のような呼び出しが可能であることを表している。

これは例えば、for_eachのようなイテレータを取るアルゴリズムにおいて、処理をカスタマイズする関数オブジェクトの制約に用いることができる。

備考

indirectly_unary_invocableindirectly_regular_unary_invocableの違いは意味論的な要件のみである。indirectly_regular_unary_invocableはその呼び出しに等しさの保持を要求し、表明する。詳細はinvocable/regular_invocableを参照のこと。

#include <iostream>
#include <concepts>
#include <iterator>
#include <vector>
#include <memory>

template<typename I, std::indirectly_unary_invocable<I> F>
void f(const char* nameI, const char* nameF) {
  std::cout << nameI << " is indirectly_unary_invocable " << nameF << std::endl;
}

template<typename I, typename F>
void f(const char* nameI, const char* nameF) {
  std::cout << nameI << " is not indirectly_unary_invocable " << nameF << std::endl;
}

using F1 = decltype([](const int&) -> int { return 0; });
using F2 = decltype([](int&&) -> int { return 0; });

int main() {
  f<int*, F1>("int*", "int(const int&)");
  f<std::unique_ptr<int>, F1>("std::unique_ptr<int>", "int(const int&)");
  f<std::vector<int>::iterator, F1>("std::vector<int>::iterator", "int(const int&)");
  f<std::istream_iterator<int>, F1>("std::istream_iterator<int>", "int(const int&)");

  std::cout << "\n";

  f<int*, F2>("int*", "int(int&&)");
  f<std::unique_ptr<int>, F2>("std::unique_ptr<int>", "int(int&&)");
  f<std::vector<int>::iterator, F2>("std::vector<int>::iterator", "int(int&&)");
  f<std::istream_iterator<int>, F2>("std::istream_iterator<int>", "int(int&&)");
}

出力

int* is indirectly_unary_invocable int(const int&)
std::unique_ptr<int> is indirectly_unary_invocable int(const int&)
std::vector<int>::iterator is indirectly_unary_invocable int(const int&)
std::istream_iterator<int> is indirectly_unary_invocable int(const int&)

int* is not indirectly_unary_invocable int(int&&)
std::unique_ptr<int> is not indirectly_unary_invocable int(int&&)
std::vector<int>::iterator is not indirectly_unary_invocable int(int&&)
std::istream_iterator<int> is not indirectly_unary_invocable int(int&&)

バージョン

言語

  • C++20

処理系

関連項目

参照