- functional[meta header]
- std[meta namespace]
- function_ref[meta class]
- function[meta id-type]
- cpp26[meta cpp]
template<class F> function_ref(F* f) noexcept; // (1)
template<class F>
constexpr function_ref(F&& f) noexcept; // (2)
template<auto f>
constexpr function_ref(nontype_t<f>) noexcept; // (3)
template<auto f, class U>
constexpr function_ref(nontype_t<f>, U&& obj) noexcept; // (4)
template<auto f, class T>
constexpr function_ref(nontype_t<f>, /*cv*/ T* obj) noexcept; // (5)
constexpr function_ref(const function_ref&) noexcept = default; // (6)
- nontype_t[link /reference/utility/nontype_t.md]
function_ref
オブジェクトを構築する。
function_ref
クラステンプレートパラメータのnoexcept例外指定 noex に応じて、説明用のbool
型テンプレート定数is-invocable-using<T...>
を次のように定義する :
- noex が
true
のとき :is_nothrow_invocable_r_v
<R, T..., ArgTypes...>
- noex が
false
のとき :is_invocable_r_v
<R, T..., ArgTypes...>
function_ref
オブジェクトは、説明専用のメンバ変数thunk-ptr
とbound-entity
を保持する。
function_ref
クラステンプレートパラメータのCV修飾子 cv に応じて
- (1) :
is_function
<F>
がtrue
、かつis-invocable-using<F>
がtrue
であること - (2) :
T
をremove_reference_t
<F>
としたときremove_cvref_t
<F>
がfunction_ref
と同一型ではなく、かつis_member_pointer_v
<T>
がfalse
であり、かつis-invocable-using</*cv*/ T&>
がtrue
であること
- (3) :
F
をdecltype(f)
としたときis-invocable-using<F>
がtrue
であること
- (4) :
T
をremove_reference_t
<F>
、F
をdecltype(f)
としたときis_rvalue_reference_v
<U&&>
がfalse
であり、かつis-invocable-using<F, /*cv*/ T&>
がtrue
であること
- (5) :
F
をdecltype(f)
としたときis-invocable-using<F, /*cv*/ T*>
がtrue
であること
- (3), (4), (5) :
F
をdecltype(f)
としたとき、is_pointer
<F> ||
is_member_pointer
<F>
がtrue
ならば、f
がヌルポインタでないこと。
- (1) :
f
がヌルポインタでないこと。
function_ref
クラステンプレートパラメータのCV修飾子 cv に応じて
- (1) :
bound-entity
をf
で、thunk-ptr
を説明専用の関数thunk
へのアドレスで初期化する。- 関数呼び出し
thunk(bound-entity, call-args...)
はinvoke_r
<R>(f, call-args...)
と等価。
- 関数呼び出し
- (2) :
bound-entity
をaddressof
(f)
で、thunk-ptr
を説明専用の関数thunk
へのアドレスで初期化する。- 関数呼び出し
thunk(bound-entity, call-args...)
はinvoke_r
<R>(static_cast</*cv*/ T&>(f), call-args...)
と等価。
- 関数呼び出し
- (3) :
bound-entity
を未規定オブジェクトへのポインタまたはヌルポインタで、thunk-ptr
を説明専用の関数thunk
へのアドレスで初期化する。- 関数呼び出し
thunk(bound-entity, call-args...)
はinvoke_r
<R>(f, call-args...)
と等価。
- 関数呼び出し
- (4) :
bound-entity
をaddressof
(obj)
で、thunk-ptr
を説明専用の関数thunk
へのアドレスで初期化する。- 関数呼び出し
thunk(bound-entity, call-args...)
はinvoke_r
<R>(f, static_cast</*cv*/ T&>(obj), call-args...)
と等価。
- 関数呼び出し
- (5) :
bound-entity
をobj
で、thunk-ptr
を説明専用の関数thunk
へのアドレスで初期化する。- 関数呼び出し
thunk(bound-entity, call-args...)
はinvoke_r
<R>(f, obj, call-args...)
と等価。
- 関数呼び出し
- (6) : コピーコンストラクタ。
投げない
#include <functional>
#include <iostream>
#include <utility>
int ident_func(int x)
{ return x; }
struct ident_functor {
int operator()(int x) const
{ return x; }
};
struct X {
int ident_func(int x) const
{ return x; }
};
int main()
{
// (1) 関数ポインタ
{
std::function_ref<int(int)> f1 = &ident_func;
std::cout << "(1) : " << f1(1) << std::endl;
}
// (2) 関数オブジェクト
{
ident_functor functor;
std::function_ref<int(int)> f2 = functor;
std::cout << "(2) : " << f2(2) << std::endl;
}
// (3) メンバ関数
{
std::function_ref<int(X&, int)> f3 = std::nontype<&X::ident>;
X obj;
std::cout << "(3) : " << f3(obj, 3) << std::endl;
}
// (4), (5) メンバ関数+オブジェクト束縛
{
X obj;
std::function_ref<int(int)> f4{std::nontype<&X::ident>, obj};
std::cout << "(4) : " << f4(4) << std::endl;
std::function_ref<int(int)> f5{std::nontype<&X::ident>, &obj};
std::cout << "(5) : " << f5(5) << std::endl;
}
// (6) コピーコンストラクタ
{
std::function_ref<int(int)> f1 = &ident_func;
std::function_ref<int(int)> f6 = f1;
std::cout << "(6) : " << f6(6) << std::endl;
}
}
- std::nontype[link /reference/utility/nontype_t.md]
(1) : 1
(2) : 2
(3) : 3
(4) : 4
(5) : 5
(6) : 6
- C++26
- Clang: ??
- GCC: ??
- ICC: ??
- Visual C++: ??