std::invoke
개요
지정 된 인수를 사용 하 여 호출 가능 개체를 호출 합니다. C + + 17에 추가 되었습니다.
template <class Callable, class... Args>
invoke_result_t<Callable, Args...>
invoke(Callable&& fn, Args&&... args) noexcept(/* specification */);
매개 변수
호출 호출할 개체의 형식입니다.
Args 호출 인수의 형식입니다.
fn 호출할 개체입니다.
args 호출 인수입니다.
사양의
noexcept
사양 std::is_nothrow_invocable_v<Callable, Args>)
입니다.
설명
매개 변수 인수를 사용 하 여 호출 가능 개체 fn 을 호출 합니다. 실제로 INVOKE(std::forward<Callable>(fn), std::forward<Args>(args)...)
의사 (pseudo) 함수는 INVOKE(f, t1, t2, ..., tN)
다음 중 하나를 의미 합니다.
-
f
가T
클래스의 멤버 함수에 대한 포인터이고,t1
이T
형식의 개체이거나T
형식의 개체에 대한 참조 또는T
에서 파생된 형식의 개체에 대한 참조인 경우(t1.*f)(t2, ..., tN)
입니다. 즉,가 true 인 경우입니다std::is_base_of<T, std::decay_t<decltype(t1)>>::value
. -
(t1.get().*f)(t2, ..., tN)``f
가 클래스의 멤버 함수에 대 한 포인터T
이 고는std::decay_t<decltype(t1)>
의 특수화입니다std::reference_wrapper
. -
((*t1).*f)(t2, ..., tN)``f
가 클래스의 멤버 함수에 대 한 포인터이T
고가t1
이전 형식 중 하나가 아닌 경우 -
N == 1이며
f
가T
클래스의 멤버 데이터에 대한 포인터이고,t1
이T
형식의 개체이거나T
형식의 개체에 대한 참조 또는T
에서 파생된 형식의 개체에 대한 참조인 경우t1.*f
입니다. 즉,가 true 인 경우입니다std::is_base_of<T, std::decay_t<decltype(t1)>>::value
. -
t1.get().*f
N = = 1이 고는f
클래스의 멤버 데이터에 대 한 포인터이T
고는std::decay_t<decltype(t1)>
의 특수화입니다std::reference_wrapper
. -
(*t1).*f
N = = 1이 고f
는 클래스의 멤버 데이터에 대 한 포인터이T
고는t1
이전 형식 중 하나가 아닙니다. -
다른 모든 경우에는
f(t1, t2, ..., tN)
.
예제
// functional_invoke.cpp
// compile using: cl /EHsc /std:c++17 functional_invoke.cpp
#include <functional>
#include <iostream>
struct Demo
{
int n_;
Demo(int const n) : n_{n} {}
void operator()( int const i, int const j ) const
{
std::cout << "Demo operator( " << i << ", "
<< j << " ) is " << i * j << "\n";
}
void difference( int const i ) const
{
std::cout << "Demo.difference( " << i << " ) is "
<< n_ - i << "\n";
}
};
void divisible_by_3(int const i)
{
std::cout << i << ( i % 3 == 0 ? " is" : " isn't" )
<< " divisible by 3.\n";
}
int main()
{
Demo d{ 42 };
Demo * pd{ &d };
auto pmf = &Demo::difference;
auto pmd = &Demo::n_;
// Invoke a function object, like calling d( 3, -7 )
std::invoke( d, 3, -7 );
// Invoke a member function, like calling
// d.difference( 29 ) or (d.*pmf)( 29 )
std::invoke( &Demo::difference, d, 29 );
std::invoke( pmf, pd, 13 );
// Invoke a data member, like access to d.n_ or d.*pmd
std::cout << "d.n_: " << std::invoke( &Demo::n_, d ) << "\n";
std::cout << "pd->n_: " << std::invoke( pmd, pd ) << "\n";
// Invoke a stand-alone (free) function
std::invoke( divisible_by_3, 42 );
// Invoke a lambda
auto divisible_by_7 = []( int const i ) {
std::cout << i << ( i % 7 == 0 ? " is" : " isn't" )
<< " divisible by 7.\n";
};
std::invoke( divisible_by_7, 42 );
}
Output
Demo operator( 3, -7 ) is -21
Demo.difference( 29 ) is 13
Demo.difference( 13 ) is 29
d.n_: 42
pd->n_: 42
42 is divisible by 3.
42 is divisible by 7.