2013-08-13 2 views
2

저는 펑터에 함수 포인터를 캡처하려고하는데 왜 그럴 수 없는지 이해하지 못합니다.C++에서 매개 변수를 사용하여 함수 포인터를 만들 수 있습니까?

은 Functor 클래스 :

다른 곳에서 코드의
template <class C> 
class MyFunctor : public BaseFunctor { 
    public: 
    typedef long (C::*t_callback)(const long, const char *); 

    MyFunctor (void) : BaseFunctor(), obj(NULL), callback(NULL) {} 
    virtual long operator() (const long a, const char *b) { 
     if (obj && callback) { 
      (obj->*callback)(a,b); 
     } 
    } 

    C *obj; 
    t_callback callback; 
}; 

:

... function call missing argument list; ...

:

함수 서명이 다음 long C::Func (const long, const char *)

MyFunctor funky; 
funky.obj = this; 
funky.callback = Func; 

나는 오류입니다3210

왜 작동하지 않습니까?

편집 : 아래의 제안을 통해 나는 특정 구현 작업을 수행하는 간단한 솔루션을 발견했습니다.

funky.callback = &C::Func;

+2

당신은 내가이 기능의 인식이다 표준 기능 – aaronman

+0

를 사용하지 않는 이유를. 나는 STL의 어떤 것에도 혐오감이 없다. 답변을 예로 들어 주시면 받아 들일 수 있습니까? 또한 C++이 매개 변수와 std :: function의 필요성을 처리 할 수없는 이유에 대해 자세히 설명 할 수 있습니까? – Zak

+0

괜찮 았던 것은 실제로 당신이하려고했던 것을 얻지 못했지만 어떻게 함수 포인터 대신 작동하는지에 대한 예제를주었습니다. – aaronman

답변

2

나는 당신이 당신의 코드를하지만, 함수 포인터가 std::functionstd::mem_fn 여기 사이트에서 std::function를 사용의 예보다 훨씬 사용하기 쉽게이 개 C++ 기능에서 일을하려고 무엇을 100 % 확실하지 않다 .

#include <functional> 
#include <iostream> 

struct Foo { 
    Foo(int num) : num_(num) {} 
    void print_add(int i) const { std::cout << num_+i << '\n'; } 
    int num_; 
}; 

void print_num(int i) 
{ 
    std::cout << i << '\n'; 
} 

struct PrintNum { 
    void operator()(int i) const 
    { 
     std::cout << i << '\n'; 
    } 
}; 

int main() 
{ 
    // store a free function 
    std::function<void(int)> f_display = print_num; 
    f_display(-9); 

    // store a lambda 
    std::function<void()> f_display_42 = []() { print_num(42); }; 
    f_display_42(); 

    // store the result of a call to std::bind 
    std::function<void()> f_display_31337 = std::bind(print_num, 31337); 
    f_display_31337(); 

    // store a call to a member function 
    std::function<void(const Foo&, int)> f_add_display = &Foo::print_add; 
    Foo foo(314159); 
    f_add_display(foo, 1); 

    // store a call to a function object 
    std::function<void(int)> f_display_obj = PrintNum(); 
    f_display_obj(18); 
} 

코드에서 함수 포인터 :

typedef long (C::*t_callback)(const long, const char *); 

하려면이 std::funciton 할 :

std::function<long(const long,const char*)> t_callback = something;

+0

왜 std :: function이 필요한지와 왜 이것이 일반 C++ 구문으로 성취 될 수 없는지에 대해 더 설명 할 수 있습니까? – Zak

+0

"함수 객체에 대한 호출 저장"을 시도했지만 이전과 같은 오류가 발생했습니다. – Zak

2

당신은

  1. 하나를 반환 unsigned long 다른 반환 long 때문에 유형 long (C::*)(const long, const char *)의 변수에 서명 unsigned long Func (const long, const char *)와 기능을 할당 할 수 없습니다.
  2. 하나는 구성원에 대한 포인터이고 다른 하나는 비 멤버 "자유"기능의 이름입니다.

당신이 Func가 단순히 C 객체없이 호출 할 경우, 당신은 t_callback에서 C::을 제거해야합니다. Func이 실제로 멤버 함수이고 서명 (은 코드를 바꿔 쓰지 마십시오!) &ThisClass::Func에서와 같이 멤버에 대한 포인터 값을 만들 때 :: 연산자를 사용해야합니다.

표시되는 특수한 오류는 이름에 대해 과부하 해결이 수행 되었기 때문입니다. 컴파일러는 당신이 그 이름을 가지고 있음을 알지만, 그 이름을 가진 것들 (잠재적으로 많은 것들이있을 수 있음)이 주어진 표현에서 작동하지 않는다고보고합니다.


다른 사람들이 언급했듯이 이것은 실제로 프로젝트에서 사용해야하는 것이 아닙니다.이러한 종류의 기능은 std::functionstd::bind으로 처리되며 표준화 된 TR1 라이브러리를 사용하여 C++ 03에서도 사용할 수 있으므로 직접 수행하는 것이 가장 좋은 방법입니다.

사용자 지정 코드를 작성하지 않고, 당신이, 포인터 - 투 - 회원 Func 방법을 얻을 그것은 현재 this 포인터를 부착

std::function< long(long, char *) > funky = std::bind(&MyClass::Func, this); 

할 수있는, 그것은 주변의 간접 통화 래퍼를 생성 모두 this의 유효 기간 동안 유효합니다.

funky(3, "hello"); 

는 간접 호출을 방지 std::function를 선언 피하기 위해 auto를 사용하십시오. 일회용 유형의 물체를 얻을 수 있습니다. (당신은 또 다른 기능을 할당 할 수 없습니다.)

auto funky = std::bind(&MyClass::Func, this); 
+0

# 1이 옳다. 왜냐하면 내가 "시끄 럽"한 예에서 오타를 남겼 기 때문이다. – Zak

+0

# 2가 더 많은 목표이며, 이것이 내 원래 질문에 대한 답변이라고 생각합니다. – Zak

+0

실제로 실제 문제를 진단하기위한 체크 표시를해야합니다. 그러나, 당신이 진술 한대로, 나의 방법은 제일 개인 운동으로 남겨두고, 나가 실제로하는 것을 시도하고있는 무슨을 달성하는 적합한 방법은이다 std :: function, 그래서 나는 당신에게 +1 및 @aaronman 수표를 줄 것이다 그래서 내 것과 비슷한 문제를 가진 사람들이 먼저 대답을 보게 될 것입니다. 감사! – Zak