std::invoke
是 C++17 引入的一个标准库函数,用于调用可调用对象,它一般用于模板中,能够以一致的方式处理不同类型的可调用对象。
_Functor
: 普通函数对象或 lambda。_Pmf_object
: 通过对象调用成员函数_Pmf_pointer
:通过对象指针调用成员函数_Pmd_object
: 通过对象访问成员数据_Pmd_pointer
:通过对象指针访问成员数据_Pmd_refwrap
:引用包装的成员数据指针,通过reference_wrapper
访问。_Pmf_refwrap
:引用包装的成员函数指针,通过reference_wrapper
调用。
_template <class _Callable, class _Ty1, class... _Types2>
constexpr auto invoke(_Callable&& _Obj, _Ty1&& _Arg1, _Types2&&... _Args2)
noexcept(
noexcept(_Invoker1<_Callable, _Ty1>::_Call(
static_cast<_Callable&&>(_Obj),
static_cast<_Ty1&&>(_Arg1),
static_cast<_Types2&&>(_Args2)...)
)
)
-> decltype(_Invoker1<_Callable, _Ty1>::_Call(
static_cast<_Callable&&>(_Obj),
static_cast<_Ty1&&>(_Arg1),
static_cast<_Types2&&>(_Args2)...)
)
{
if constexpr (_Invoker1<_Callable, _Ty1>::_Strategy == _Invoker_strategy::_Functor)
{
return static_cast<_Callable&&>(_Obj)(static_cast<_Ty1&&>(_Arg1), static_cast<_Types2&&>(_Args2)...);
}
else if constexpr (_Invoker1<_Callable, _Ty1>::_Strategy == _Invoker_strategy::_Pmf_object)
{
return (static_cast<_Ty1&&>(_Arg1).*_Obj)(static_cast<_Types2&&>(_Args2)...);
}
else if constexpr (_Invoker1<_Callable, _Ty1>::_Strategy == _Invoker_strategy::_Pmf_refwrap)
{
return (_Arg1.get().*_Obj)(static_cast<_Types2&&>(_Args2)...);
}
else if constexpr (_Invoker1<_Callable, _Ty1>::_Strategy == _Invoker_strategy::_Pmf_pointer)
{
return ((*static_cast<_Ty1&&>(_Arg1)).*_Obj)(static_cast<_Types2&&>(_Args2)...);
}
else if constexpr (_Invoker1<_Callable, _Ty1>::_Strategy == _Invoker_strategy::_Pmd_object)
{
return static_cast<_Ty1&&>(_Arg1).*_Obj;
}
else if constexpr (_Invoker1<_Callable, _Ty1>::_Strategy == _Invoker_strategy::_Pmd_refwrap)
{
#if defined(__clang__) || defined(__EDG__) // TRANSITION, VSO-1956799
return _Arg1.get().*_Obj;
#else // ^^^ no workaround / workaround vvv
auto& _Ref = _Arg1.get();
return _Ref.*_Obj;
#endif // ^^^ workaround ^^^
}
else
{
_STL_INTERNAL_STATIC_ASSERT(_Invoker1<_Callable, _Ty1>::_Strategy == _Invoker_strategy::_Pmd_pointer);
return (*static_cast<_Ty1&&>(_Arg1)).*_Obj;
}
}
template <class _Callable, class _Ty1, class _Removed_cvref>
struct _Invoker1<_Callable, _Ty1, _Removed_cvref, true, false>
: conditional_t<
is_same_v<typename _Is_memfunptr<_Removed_cvref>::_Class_type, _Remove_cvref_t<_Ty1>>||
is_base_of_v<typename _Is_memfunptr<_Removed_cvref>::_Class_type, _Remove_cvref_t<_Ty1>>,
_Invoker_pmf_object,
conditional_t<_
// 检查 _Ty1 是否是 std::reference_wrapper 的特化类型
Is_specialization_v<_Remove_cvref_t<_Ty1>, reference_wrapper>,
_Invoker_pmf_refwrap,
_Invoker_pmf_pointer>> {}; // pointer to member function
template <class _Callable, class _Ty1, class _Removed_cvref>
struct _Invoker1<_Callable, _Ty1, _Removed_cvref, false, true> conditional_t
: conditional_t<
is_same_v<typename _Is_member_object_pointer<_Removed_cvref>::_Class_type, _Remove_cvref_t<_Ty1>>||
is_base_of_v<typename _Is_member_object_pointer<_Removed_cvref>::_Class_type, _Remove_cvref_t<_Ty1>>,
_Invoker_pmd_object,
conditional_t<
_Is_specialization_v<_Remove_cvref_t<_Ty1>, reference_wrapper>,
_Invoker_pmd_refwrap,
_Invoker_pmd_pointer>> {}; // pointer to member data
template <class _Callable, class _Ty1, class _Removed_cvref>
struct _Invoker1<_Callable, _Ty1, _Removed_cvref, false, false> : _Invoker_functor {};
template <class _Callable, class _Ty1, class _Removed_cvref = _Remove_cvref_t<_Callable>,
bool _Is_pmf = is_member_function_pointer_v<_Removed_cvref>,
bool _Is_pmd = is_member_object_pointer_v<_Removed_cvref>>
struct _Invoker1;