최근에 람다와 함수 포인터에 대해 배우고 있으며 간단한 콜백 시스템에서 사용하고 싶었습니다. 이벤트를 저장하는지도와 트리거 될 때 호출해야하는 모든 콜백은 다음과 같습니다
std::unordered_map< sf::Event::EventType , std::vector< Callback > > eventMap;
.
나는 이런 식으로 콜백을 정의했다 typedef void(*Callback)(sf::Event const&);
. 내 registerEvent()
함수는 이벤트와 콜백을 인수로받습니다.
registerEvent()
그런 다음 다음과 같이 호출 할 수 있습니다.
inputHandler.registerEvent(/*Any event type*/, [](sf::Event const&)
{
//do something
});
그것은 잘 작동하지만 객체를 캡처하고 싶을 때 error: no matching function for call to ‘InputHandler::registerEvent(sf::Event::EventType, Button::Button(ID, Callback, InputHandler&)::<lambda(const sf::Event&)>)’
그 오류를 생성하는 코드는 다음과 같습니다.
class Button
{
//
public:
Button(ID id, Callback callback, InputHandler& inputhandler)
{
inputhandler.registerEvent(sf::Event::MouseButtonPressed, [this](sf::Event const&)
{
{
getTextureRect();
}
});
}
};
것처럼 보인다 this
캡처가와는 호환되지 않는 람다의 유형 변화 registerEvent()
기능. 그러나 많은 다른 클래스가 그러한 람다를 만들 수 있어야하고 캡처가없는 람다도 벡터에 포함되어야하므로 벡터가 어떤 유형이어야하는지 어떻게 알 수 있는지 모르겠습니다. 나는 들었지만 std::function
(어리석게 들릴 수 있음) 더 나은 이해를 위해 C-Style 방식을 사용하고 싶습니다. 나는 이것을 생각 한다포스트는 그것에 대해 뭔가를 말했지만 나는 그것을 잘 이해하지 못합니다. 나는 두 개의 맵을 만드는 것에 대해 생각했습니다. 하나는 캡처가없는 모든 람다를위한 것이고 다른 하나는 다른 하나를위한 것입니다. 그런 다음 모든 클래스가 기본 클래스에서 상속되도록하고 벡터의 캡처 유형을 기본 클래스에 대한 포인터로 만들 수 있습니다. 그러나 이것은 매우 복잡하고 불필요한 오버 헤드를 추가하고 이것이 작동하는지조차 모릅니다. 이와 같은 상황에 대한 일반적인 해결책은 무엇입니까?
모든 답변과 안부 감사합니다.
Daniel Schreiber Mendes :)
편집 :
콜백은 이제 다음과 같이 보입니다.typedef std::function< void(sf::Event const&) > Callback;
사용하고 싶을 때 :
//inside the Button Constructor
inputhandler.registerEvent(sf::Event::MouseButtonPressed, Callback([this](sf::Event const& event)
{
//memberFunc();
}));
이것은 나에게 오류를주지는 않았지만 잘못된 방식으로 행동했습니다. 람다를 실행했지만 정의 된 클래스는 변경되지 않았습니다. 그래서 방금 생성 된 객체의 주소를 인쇄하는 라인을 생성자에 추가했습니다. Button을 하나만 만들고 있으므로 주소가 하나만 인쇄되어야합니다. 그러나 두 가지가있었습니다. 즉, std :: function에 래핑 된 람다를 벡터에 삽입하면 새 Button 객체가 생성됩니다. 어떻게 그렇게 될수 있니? 암시 적 객체 생성?
귀하의 답변에 감사드립니다 :)
캡처가있는 Lambda는 함수 포인터로 변환 할 수 없습니다. 일반 함수 포인터는 람다의 캡처를위한 상태를 저장할 곳이 없습니다.
std::function
객체이므로 캡처를 포함하거나 포함하지 않고 람다를 저장할 수 있습니다.
원시 함수 포인터를 사용해야하는 경우 함수 포인터와 상태를 저장 한 다음 호출 할 때 함수에 상태를 전달해야합니다. 예 :
typedef void(*Callback)(sf::Event const&, void* data);
std::unordered_map< sf::Event::EventType , std::vector< std::pair< Callback, void* > > > eventMap;
그런 다음 상태를 객체에 저장하고 객체를 어딘가에 저장하여 살아남 아야합니다. 개체 내부에서 void*
다시 상태 개체 포인터 로 캐스팅해야합니다 . 일반 함수 포인터가 필요한 ac 라이브러리를 사용 std::function
하지 않는 경우이 모든 작업을 수행하는 것이 훨씬 간단 합니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다