2015-01-15 2 views
1

아래에 표시된 간단한 코드에는 함수를 인수로받는 run7 함수가 있습니다. main 함수에서 함수 test이 전달되고 올바르게 작동합니다. 그러나 내 method2method1이이 함수를 전달할 수 없습니다. 그것은 원인이 오류 :C++에서 다른 메서드를 인수로 전달

내가 run7의 구조를 변경하지 않고 run7method1을 통과 호출 할
main.cpp:24:15: error: cannot convert ‘A::method1’ from type ‘void (A::)(int)’ to type ‘void (*)(int)’ 
    run7(method1); 
      ^

. method2을 수정하는 방법은 무엇입니까?

#include <iostream> 

using namespace std; 

void run7 (void (*f)(int)) 
{ 
    f(7); 
} 

void test(int a) 
{ 
    cout<<a<<endl; 
} 

class A 
{ 
public: 

    int m=4; 

    void method1(int a) 
    { 
     cout<< a*m <<endl; 
    } 

    void method2() 
    { 
     run7(method1); 
    } 
}; 

int main() 
{ 
    run7(test); 
    return 0; 
} 
+0

기능 포인터가 아니라 당신이 대신 수행 할 수있는

는 형식 삭제 펑터를 취할 run을 변경할 수있다 메소드 포인터와 동일합니다. 이것을 조금 더 연구해야합니다. – Cameron

+0

당신은 바인드 또는 다른 마법과 함께 할 수 있습니다. 문제는 method1이 nonstatic이기 때문에'method1'의 타입이'void (A :: *) (int)'이고 당신이 분명히 타입 인'void (*) (int) '타입의 인자를 받아들이 길 원합니다. 같은 것이 아닙니다. method1을 실제로 전달하려면 정적으로 만들어야합니다. – Creris

답변

4

당신이 자세히 오류 보면 : 당신은 유형이 다른 것을 알 수

error: cannot convert ‘A::method1’ from type ‘void (A::)(int)’ to type ‘void (*)(int)’

. 왜냐하면 클래스 메소드는 원시 함수와 동일한 유형이 아니기 때문입니다. 호출하려면 추가 객체가 필요합니다. method1을 호출하려면 A이 필요하며 원시 함수 포인터로 전달할 수없는 저장소가 필요하므로 컴파일 할 코드가 없습니다.

void run7 (std::function<void(int)> f) { 
    f(7); 
} 

그리고 또한 this에 전달하는 펑 전달 :

void method2() 
{ 
    run7(std::bind(&A::method1, this,   // option 1 
        std::placeholders::_1)); 
    run7([this](int x){ this->method1(x); }); // option 2 
} 
+0

option1이 선호되지만 '오류 : 변환 할 수 없습니다'std :: bind (_Func &&, _BoundArgs && ...) [_Func = void (A :: *) (int); _BoundArgs = {A * const}; typename std :: _ Bind_helper :: std :: is_enum :: :: 값 :: _Func, _BoundArgs ...> :: type = std :: _ Bind ((* & this)) 'from'std :: _ Bind_helper :: function ' run7 (std :: bind (& A :: method1, this));' – barej

+0

method1은 정적 일 수 없다고 가정했습니다. 그것을 해결할 수 있습니까? – barej

+0

감사합니다. 'std :: placeholders'는 여기서 무엇을합니까? – barej

2

run7을 호출 템플릿이되도록 사용할 수있는 템플릿으로 만듭니다.

그런 다음 λ 기능을 사용하여 method2에서 호출하십시오.

void method2() 
{ 
    run7([=](int arg){this->method1(arg)];}); 
} 

업데이트

당신은 그것을 청소하기 위해 보편적 참조와 완벽한 전달을 사용 run7의 더 나은 버전을 사용할 수 있습니다 (덕분에 제안에 대한 @Quentin 예정이다).

template <typename F> 
void run7(F&& f) 
{ 
    std::forward<F>(f)(7); 
} 
+0

깨끗한 답변을 위해 범용 참조 및 완벽한 전달 기능을 사용하는 것을 잊지 마십시오. – Quentin

+0

@Quentin, 나는 당신의 표류를 따르지 않습니다. 이 예에서 범용 참조와 완벽한 전달은 어디에서 작동합니까? –

+0

함수 오브젝트 자체를 전달할 때, 즉'F && f'와'std :: forward (f) (7);'. – Quentin

관련 문제