2009-07-08 5 views
2

어떻게 이것을 컴파일 할 수 있습니까? boost :: ref()를 사용하여 시작하면 오류가 발생합니다. boost :: ref는 C++ 알고리즘 클래스에 대한 참조를 전달하는 데 사용되는 것으로 생각했습니다. 사람들이 제안Boost :: ref를 올바르게 사용하면 ..?

list<Object> lst; 
    lst.push_back(Object(1,2.0f)); 
    lst.push_back(Object(3,4.3f)); 

    struct between_1_and_10 
    { 
    int d; 
    void operator() (Object& value) 
    { 
     value.a += 5; value.b -= 3.3f; 
     cout << d << endl; 
     d += value.a; 
    } 
    }; 

    between_1_and_10 val; 
    val.d = 4; 
    for_each(lst.begin(), lst.end(), boost::ref(val)); // Problem is here 
    printf("rg"); 

편집 다음은 컴파일러 오류입니다 :

1>c:\program files (x86)\microsoft visual studio 9.0\vc\include\algorithm(29) : error C2064: term does not evaluate to a function taking 1 arguments 
1>  c:\users\swangrun\desktop\minescout work\feat-000-gettargetimages\minescouttest\maintest.cpp(102) : see reference to function template instantiation '_Fn1 std::for_each<std::list<_Ty>::_Iterator<_Secure_validation>,boost::reference_wrapper<T>>(_InIt,_InIt,_Fn1)' being compiled 
1>  with 
1>  [ 
1>   _Fn1=boost::reference_wrapper<main::between_1_and_10>, 
1>   _Ty=Object, 
1>   _Secure_validation=true, 
1>   T=main::between_1_and_10, 
1>   _InIt=std::list<Object>::_Iterator<true> 
1>  ] 
+0

확인. for_each() 행에 있어야합니다. 그러나 문제는 무엇입니까. 오류를 재현 할 수있는 오류 또는 충분한 코드를 제공해야합니다. –

+0

문제는 컴파일되지 않는다는 것입니다. 나는 대답을 받아 들였습니다, 참여해 주셔서 감사합니다! – sivabudh

+0

Martin이 의미하는 바는 "오류 메시지의 텍스트를 복사하여 질문에 붙여 넣기"입니다. 그렇게하면 컴파일러가 말하는 것을 여러분에게 설명 할 수 있습니다. 아마도 오류를 찾는 데 필요한 모든 정보를 제공했을 것입니다.적어도 컴파일러 오류 텍스트를 검색하는 다른 사람들이 질문과 대답을 찾을 수 있도록이 작업을 수행해야합니다. –

답변

7

이 당신이 정말로 원하는 :

for_each(lst.begin(), lst.end(), boost::bind<void>(boost::ref(val),_1 )); 

편집 : OP의 요청에 따라 일부 설명. for_each()는 함수를 취하지 만 단순히 struct에 대한 참조를 전달한 것뿐입니다 (예, struct에 과부하되었지만 전달하지 않았습니다). bind()는 기본적으로 구조체 내부의 함수를 "노출"합니다.

EDIT2 : "_1"에 대한 설명은 아래 설명에서 확인할 수 있습니다.

+0

감사합니다. 정확히 내가 무엇을 찾고 있었는지. 너무 성가신 일이 아니라면 왜 바인딩이 필요한지 상세히 설명해 주시겠습니까? 그리고 그 재미있는 모습은 무엇입니까? 미안해, 부스트가 처음이야. (물론, 방금 사용했던 기술의 어딘가에 좋은 자습서가 있습니다.) – sivabudh

+1

컴파일러가 boost : ref에 싸여있는 함수의 반환 유형을 추론 할 수 없기 때문에 바인딩이 필요할 것입니다. "_1"에 관해서는 http://www.boost.org/doc/libs/1_39_0/libs/bind/bind.html#with_functions –

+0

-1에서 _1은 람다 자리 표시 자입니다. for_each의 iterator가 가리키는 "현재"항목을 실제로 나타냅니다. – paxos1977

-1

가 부스트 :: 심판없이보십시오.

12

boost::reference_wrapper (이는 boost::ref이 반환합니다)은 operator()을 오버로드하지 않습니다. 당신은 boost::bind과 함께 사용할 수 있습니다. 특별한 치료법이 있습니다 (ref을 사용하지 않으면 bind은 제공된 함수 객체를 복사합니다).

그러나 for_each은 항목을 호출하는 함수 개체를 반환합니다. 그래서 그냥이

between_1_and_10 val; 
val.d = 4; 
val = for_each(lst.begin(), lst.end(), val); 
printf("rg"); 

그것은 복사 val에 물건을 호출하고 마지막 호출 이후의 같은 함수 객체를 반환 할. 당신이 boost::ref을 사용할 수 있습니다 어디에 당신이 그것을 오용하는 것 때문에


그냥, 당신에게. 이제 변수와 함께 호출 할 경우

void g(int &i) { i++; } 

template<typename T> 
void run_g(T t) { g(t); } 

는, 그것을 복사합니다 : 다른 기능을 값의 매개 변수를 사용하고, 호출하는 템플릿을 상상해보십시오. 흔히 합당한 결정입니다. 예를 들어 시작 매개 변수로 스레드에 데이터를 전달하려는 경우 로컬 함수에서 스레드 객체로 복사 할 수 있습니다. 그러나 때로는 복사하지 않고 참조를 실제로 전달할 수 있습니다. 이것은 boost::reference_wrapper가 도움이되는 곳입니다. 실제로 다음 우리가 기대하지, 출력 1 : 바인딩 인수

int main() { 
    int n = 0; 
    run_g(boost::ref(n)); 
    std::cout << n << std::endl; 
} 

이 사본은 좋은 기본값입니다. 또한 쉽게 배열과 함수를 포인터로 붕괴시킵니다 (참조로 받아들이면 T이 배열/함수 유형이 될 수 있으며 일부 문제가 발생할 수 있습니다).

관련 문제