2009-03-29 3 views
4

함수 개체를 전달하는 다음 작은 프로그램에 어떤 문제가 있습니까?함수 개체 전달 : 오류

#include <iostream> 
#include <functional> 

void foo(const std::unary_function<const std::string&, void>& fct) { 
    const std::string str = "test"; 
    fct(str); // error 
} 

class MyFct : public std::unary_function<const std::string&, void> { 
public: 
    void operator()(const std::string& str) const { 
    std::cout << str << std::endl; 
    } 
}; 

int main(int argc, char** argv){ 
    MyFct f; 
    foo(f); 
    return 0; 
} 

나는 6 행에서 다음과 같은 오류를 받고 있어요 :

no match for call to 
`(const std::unary_function<const std::string&, void>) (const std::string&)' 

답변

11

일반적인 실수를. unary_functionbinary_function

argument_type 
result_type 

구조체에는 추가 두 구조체 각각

first_argument_type 
second_argument_type 
result_type 

아니 더 있습니다. 그것들은 함수 객체 유형의 생성자의 편의를 위해 존재하므로, 그것들을 스스로 할 필요는 없습니다. 그러나 그들은 다형성을 나타내지 않습니다. 당신이 원하는 것은 함수 객체 래퍼입니다.

void foo(boost::function<void(const std::string&)> const& fct) { 
    const std::string str = "test"; 
    fct(str); // no error anymore 
} 

를 아니면 당신이 값을 가지고 어떤 순서에 적용하는 데 사용하는 경우 다음 foo에서 사본을 반환 할 수 있습니다 템플릿

template<typename FunctionObject> 
void foo(FunctionObject const& fct) { 
    const std::string str = "test"; 
    fct(str); // no error anymore 
} 

합니다 boost::function은 마음에 온다. 어느 것이 함수 객체가 그 멤버들 사이에 어떤 상태 변수를 업데이트 할 수있게 해준다. for_each은 그 점을 좋아하는 예입니다. 어쨌든 일반적으로 어쨌든 나는 가치가있다. 왜냐하면 그것들은 대개 작기 때문에 복사하는 것이 더 큰 유연성을 부여하기 때문이다. 그래서 나는

template<typename FunctionObject> 
void foo(FunctionObject fct) { 
    const std::string str = "test"; 
    fct(str); // no error anymore 
} 

는 그런 다음, FCT의 사본을 어딘가에 저장 할 수 있으며 fct의 연산자() const가 아닌 수 있으며 전체 지점의 일부입니다 (일부 멤버를 업데이트 할 operator()). const 참조로 함수 객체를 가져 오는 경우 사용자가 함수를 전달할 수 있으므로 일반적으로 함수 객체를 복사 할 수 없습니다. 복사하면 로컬 함수 포인터 대신 함수를 로컬로 선언합니다. 그러나 by-value를 받아들이면 함수가 전달 될 때 대신 함수 포인터를 받아 들일 수 있습니다.이 포인터는 안전하게 복사 할 수 있습니다.

+0

답변 해 주셔서 감사합니다. 부스트 솔루션은 템플릿 솔루션만큼 효율적입니까? – Frank

+0

boost 함수는 래핑 된 함수 객체에 대한 간접 호출을해야하기 때문에 효율적이지 않습니다. 하지만 템플릿이 필요 없다는 장점이 있습니다. 그 boost.function을 사용하여 어딘가에 저장할 수 있습니다 (예 : 클래스 멤버). –

+0

당신이 unary_function으로 찾은 것에 가장 가깝다고 생각합니다. –