2012-05-07 2 views
5

나는 다음과 같은 한 :은에 콜백으로 멤버 함수를 지정 C++ 11

typedef std::function<bool (const std::string&)> SomethingCoolCb; 

class ClassA 
{ 
public: 
    void OnSomethingCool(const SomethingCoolCb& cb) 
    { 
     _cb = cb; 
    } 

private: 
    SomethingCoolCb _cb; 
}; 

class ClassB 
{ 
public: 
    ClassB(); 
    bool Juggle(const std::string& arg); 

private: 
    ClassA _obj; 
}; 

내가 :: _ OBJ ClassB가에 콜백으로 ClassB가 :: 저글링() 멤버 함수를 지정합니다. 적절한 방법은 (ClassB가의 생성자에서) (11) C++에서이 것이 할 것입니다 : 내가 이해에서

ClassB::ClassB() 
{ 
    _obj.OnDoSomethingCool(
     [&](const std::string& arg) -> bool 
     { 
      return Juggle(arg); 
     }); 
} 

를, 컴파일러는 위의 람다 코드 밖으로 표준 : 함수 객체를 만들 것입니다. 따라서 콜백이 호출되면 std :: function :: operator() 멤버를 호출하고 ClassB :: Juggle()을 직접 호출하는 대신 ClassB :: Juggle()을 호출합니다. 내가 덮개 밑에서 일어나는 일에 착각하지 않는다면, 모든 것이 비효율적 인 것처럼 보입니다. 더 좋은 방법이 있습니까?

+2

람다 (예제에서와 같이)에서'this '를 캡처하는 것이 Visual Studio 2010에서는 잘 작동하지 않는다는 것에주의하십시오. –

답변

6

실제로 다형 함수가 필요한 경우에만 std::function을 사용하십시오. 그렇지 않으면 템플릿으로 만듭니다.

functor에 구성원 함수를 적용하려면 std::mem_fn을 사용한 다음 첫 번째 인수에 bind 개체를 사용하면 결과 Functor가 콜백으로 사용할 수 있습니다.

샘플 :

#include <string> 
#include <functional> 

template<typename F> 
class ClassA 
{ 
public: 
    ClassA(F f) : _cb(f) {} 

private: 
    F _cb; 
}; 

class ClassB 
{ 
public: 
    ClassB() 
    : _obj(std::bind(&ClassB::Juggle, this, 
        std::placeholders::_1)) 
    {} 
    bool Juggle(const std::string& arg) {return true;} 
private: 
    ClassA<decltype(std::bind(
         std::declval<bool (ClassB::*)(const std::string&)>() 
         , std::declval<ClassB*>() 
         , std::placeholders::_1 
        )) > _obj; 
}; 

int main() 
{ 
    ClassB b; 
    return 0; 
} 

측이 스텝 무섭게 추한가되는 비용 함수의 비용.

+0

bind() 구문은 항상 _1, _2, _3 등의 자리 표시 자 매개 변수 및하지 않습니다. 나는 C++에 람다 (lambdas)가 있다는 것을 알았습니다. bind()는 쓸모가 없습니다. 그러나 bind()가 Boost에서 나오고 현재 표준의 일부이기 때문에, 아마 나는 그 가정으로 착각했다. –

+2

@ArcadioAlivioSincero'bind'가 여전히 유용 할 수 있습니다. 때때로 그것은 더 짧습니다. 약간의 트릭을 사용하여 예제를 사이드 - 스텝'function'으로 업데이트했습니다. – pmr

+1

콜백은 대개 유연성을 위해'std :: function <>'을 사용하기에 좋은 장소입니다 (어떤 * 유형의 콜백을 등록하기 위해 * 함수 *를 사용할 수 있다고 가정하면, 그것을 저장하기 위해 유니폼이 필요합니다) –

관련 문제