개요

지정 된 인수를 사용 하 여 호출 가능 개체를 호출 합니다. 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) 다음 중 하나를 의미 합니다.

  • fT 클래스의 멤버 함수에 대한 포인터이고, t1T 형식의 개체이거나 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이며 fT 클래스의 멤버 데이터에 대한 포인터이고, t1T 형식의 개체이거나 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.