leesangwon0114

I am Research Engineer. Currently working in KT.

C++Intermediate 33. Callable Object & invoke

11 Dec 2018 » c++

codenuri 강석민 강사 강의 내용기반으로 정리한 내용입니다.


Callable Object & invoke

#include <iostream>
#include <functional>
using namespace std;

void foo()
{

}

int main()
{
    foo();

    less<int> f;
    f(1, 2);

    [](int a, int b) { return a + b; }(1, 2);
}

Function Object

  • A Function Object type is the type of an object that can be used on the left of the function call operator(괄호의 왼쪽에 올 수 있는 Object)
  • 모든 종류의 함수 포인터
  • ()연산자를 재정의한 클래스
  • Lambda Expression
  • 진짜 함수와 함수를 가리키는 참조는 Function Object 가 아니다.

#include <iostream>
#include <functional>
using namespace std;

template<typename F, typename ... Types>
decltype(auto) chronometry(F&& f, Types&& ... args)
{
    return std::forward<F>(f)(std::forward<Types>(args)...);
}

int main()
{
    chronometry(less<int>(), 10, 20);
}

멤버함수를 보낼 때 문제됨

#include <iostream>
#include <functional>
using namespace std;

template<typename F, typename ... Types>
decltype(auto) chronometry(F&& f, Types&& ... args)
{
    // std::forward<F>(f)(std::forward<Types>(args)...);
    return invoke(std::forward<F>(f), std::forward<Types>(args)...); // 멤버함수 포인터 까지 호출 가능(C++17)
}

class Dialog
{
public:
    void Close() {}
};

int main()
{
    Dialog dlg;
    chronometry(&Dialog::Close, &dlg);

    void(Dialog::*f)() = &Dialog::Close;
    (dlg.*f)(); // 멤버함수 호출 원래 코드

    // f(&dlg); // 이렇게 호출하고 싶을 때
    invoke(f, &dlg); // invoke 사용
}

#include <iostream>
#include <functional>
using namespace std;

void foo(int a, int b) {}

class Dialog
{
public:
    int color;
    void setColor(int c) { color = c; }
};

int main()
{
    invoke(&foo, 10, 20); // foo(10, 20);

    Dialog dlg;
    invoke(&Dialog::setColor, &dlg, 2); // dlg.setColor(2);

    // 멤버 변수 포인터
    invoke(&Dialog::color, &dlg) = 20; // dlg.color = 20;
    cout << dlg.color << endl; // 20
}

Callable

  • A Callable type is a type for which the INVOKE operation(used by, e.g, std::function, std::bind, and std::thread::thread) is applicable.
  • Function Object
  • Pointer to member