2009-08-06 2 views
0
class Action { 
    public: 
     void operator()() const; 
    } 

    class Data { 
    public: 
     Data(); 
     ~Data(); 
     Register(Action action) { _a = action; } 

    private: 
     Action _a; 
    } 

    class Display { 
    public: 
     Display(Data d) { d.Register(bind(Display::SomeTask, this, _1)); } 
     ~Display(); 
     void SomeTask(); 
    } 

Data의 개인 멤버 _a를 Display의 멤버 함수에 바인딩하려고하는데 d.Register를 호출 할 때 내 인수 유형이 일치하지 않는다는 컴파일 오류가 발생합니다. , 내가 도대체 ​​뭘 잘못하고있는 겁니까? 감사.호출 할 개체를 멤버 함수에 전달하십시오.

답변

4

당신이하려는 것은 완전히 명확하지 않지만 "bind"는 boost :: bind (또는 tr1 :: bind)라고 가정합니다.

바인드 문제의 커플 (디스플레이 :: SomeTask이, _1) : 그것은 그가 단항 함수를 만듭니다 때문에 _1 자리가 이해되지 않는다 & 표시 :: SomeTask

  • 해야

    • 객체와 :
      • 디스플레이 :: SomeTask는
      • 액션 :: 연산자() 인수를 취하지 않는 인수가없는
      Boost.Function을하고 Boost.Bind를 사용

    는, 여기 당신은 내가 당신이하려는 생각 무엇을 acheive에 쓸 수있는 작업은 다음과 같습니다

    typedef boost::function<void(void)> Action; 
    
    class Data { 
    public: 
        Data(); 
        ~Data(); 
        Register(Action action) { _a = action; } 
    
    private: 
        Action _a; 
    }; 
    
    class Display { 
    public: 
        Display(Data d) { d.Register(bind(&Display::SomeTask, this)); } 
        ~Display(); 
        void SomeTask(); 
    }; 
    
  • 1

    'bind'가 반환하는 것을 볼 수는 없지만 이것은 Action 클래스와 호환되지 않습니다. 또한 '복사 의미론'을 사용하고 있으므로 Action에 빈 삽입이 있으면 원하는 결과를 얻을 수 없습니다. 변경 등록 (Action * 액션)을 시도하고 'bind'가 Action 클래스의 일부 자식을 반환하도록 허용하십시오.

    또한 템플릿으로 마이그레이션 할 가능성을 검토 - 당신도 당신이 인수하지 않고 함수로 오버라이드 (override) 연산자()와 클래스로 사용할 수있을 수 있습니다이 경우 모든

    template <class A> 
    class Data { ... 
    Register(A action)... 
    A _a; 
    ... 
    

    에서 Action 클래스를 제외 할 수 있습니다보다.

    0

    첫째, 당신은 &Display::SomeTask를 사용하고 Register을 제공해야 형식을 반환 한 다음은 래퍼 *thisSomeTask를 호출해야

    • 필요에 따라 달라집니다 _1를 생략합니다.
    • 래퍼는 Display 개체 (this 대신 Shift _1)에 SomeTask을 호출해야합니다.

    그런 다음 boost::bind은 지정된 기능을 호출하는 복잡한 합성 유형을 반환합니다. 그것을 저장하는 방법이 필요합니다. 여기서는 boost::function이 유용합니다. 이것은 당신이 그것을 할 수있는 방법입니다.

    class Display; // forward-declaration 
        class Data { 
        public: 
         Data(); 
         ~Data(); 
    
         template<typename Action> 
         void Register(Action action) { _a = action; } 
    
        private: 
         boost::function<void(Display&)> _a; 
         // if wrapper should call it on `*this` 
         // boost::function<void()> _a; 
        } 
    
        class Display { 
        public: 
         // this currently makes no sense. You pass a copy. Probably you 
         // should consider pass-by-reference or processing "d" further. 
         Display(Data d) { d.Register(bind(&Display::SomeTask, _1)); } 
         // wrapper should call it on `*this`: 
         // Display(Data d) { d.Register(bind(&Display::SomeTask, this)); } 
         ~Display(); 
         void SomeTask(); 
        } 
    

    그러면 작동합니다.

    관련 문제