본문 바로가기

SW 지식/C 와 C++ 공부

[C++] std::function 은 무엇일까

std::function은,

Class template std::function is a general-purpose polymorphic function wrapper. Instances of std::function can store, copy, and invoke any CopyConstructible Callable target -- functions, lambda expressions, bind expressions, or other function objects, as well as pointers to member functions and pointers to data members.
The stored callable object is called the target of std::function. If a std::function contains no target, it is called empty. Invoking the target of an empty std::function results in std::bad_function_call exception being thrown.

출처 : https://en.cppreference.com/w/cpp/utility/functional/function

-> class template인 std::function은 '범용 다형성 함수 wrapper'입니다.
std::function의 인스턴스는 모든 CopyConstructible Callable 대상(함수, 람다 식, 바인딩 식 또는 기타 함수 개체뿐만 아니라 멤버 함수에 대한 포인터 및 데이터 멤버에 대한 포인터)을 저장, 복사 및 호출할 수 있습니다.

하지만, 아직도 정확히 잘 모르겠습니다 ㅠㅠ
그래서 한국어로 친절히 설명된 블로그들을 찾아보았습니다.

기존 함수포인터의 개념을 확장한 것이다. c++11이후부터는 callable target이 아래와 같이 다양해졌다. 따라서 기존 함수포인터만으로는 이를 cover할 수 없고, 보다 일반화된 개념이 필요해지면서 std::function이 새롭게 나온 것이다.

 

2. usage
선언하고 사용하는 방법에 대해서 아래와 같이 정리한다.

#include <functional>

std::function<리턴타입(입력 파라미터들)> 변수

void print(int a, int b);

ex) std::function<void(int, int)> fp = print;

출처 : https://chipmaker.tistory.com/entry/stdfunction-%EC%A0%95%EB%A6%AC

아하! 이제야 조금 이해가 됩니다.

-> 함수포인터는 멤버 함수를 담는데 제약이 있었던 반면, std::function을 사용하면 람다 함수, 콜백 등에 대해서도 유용하게 사용할 수 있습니다. (참고로 std::function 역시 C++11 이상부터 입니다.)

 

그럼 이어서 보고 있던 코드를 이어서 확인해보겠습니다.

// callable
std::function<Accessible*(Dali::Actor)> ConvertingFunctor = [](Dali::Actor) -> Accessible* {
  return nullptr;
};

...

// main code
auto accessible = ConvertingFunctor(actor);

ConvertingFunctor를 부르면, 연결된 람다 식을 통해 main code에서의 actor가 accessible로 변환되어 새로운 변수로 생성이 가능하게 됩니다.

 

이 외에도 아래와 같이 멤버 변수 선언 때도 사용이 가능합니다.

  std::unordered_map<int32_t, std::function<void(std::string)>> mDirectReadingCallbacks;
  std::function<void(Dali::Actor)>                              mHighlightClearAction;

또한, 이 외에도 parameter에도 std::function<> 을 사용하는 케이스도 있습니다.

  void Say(const std::string& text, bool discardable, std::function<void(std::string)> callback) override
  {
    if(!IsUp())
    {
      return;
    }

    mDirectReadingClient.method<DBus::ValueOrError<std::string, bool, int32_t>(std::string, bool)>("ReadCommand").asyncCall([=](DBus::ValueOrError<std::string, bool, int32_t> msg) {
      if(!msg)
      {
        LOG() << "Direct reading command failed (" << msg.getError().message << ")";
      }
      else if(callback)
      {
        mDirectReadingCallbacks.emplace(std::get<2>(msg), callback);
      }
    },
                                                                                                                           text,
                                                                                                                           discardable);
  }

 여기엔 보기만해도 공부할 C++ 문법이 많네요.

다른 페이지에서 살펴보겠습니다.

'SW 지식 > C 와 C++ 공부' 카테고리의 다른 글

[C++] emplace 함수  (0) 2021.09.23
[C++] unordered_map 컨테이너  (0) 2021.09.23
[C++] 람다 식 Lambda expressions  (0) 2021.09.16
[C++] mutable 변수  (0) 2021.09.03
[C++] String의 substr  (0) 2021.09.02