2009-03-23 5 views
3

나는 형태의 기능을 가지고있다. 조건은 다른 호출 사이트에서 다른 조건을 제공하기 때문에 Functor 인수로 표현되었습니다.부스트 람다 수집 크기 평가

이제는 직접 사용하는 것이 매우 간단하지만 가능하면 피해야 할 작은 쓰레기 수거 기능이나 functor 객체를 많이 선언해야합니다. Boost의 람다 라이브러리에서 이러한 문제를 해결할 수있는 방법을 찾고 있었지만 근본적인 것이 빠져 있다고 생각합니다. 나는 단지 내가 원하는 것을 할 수 없다.

나는 지금 당장 나를 괴롭혔다. 나는 std::vector 콜렉션을 data이라고한다. 내가 뒤따른 조건은 컬렉션의 size()이 특정 임계 값에 도달했을 때입니다. 본질적으로, 그렇다면 일 때 내 condition 펑크 터가 true를 반환하고 그렇지 않은 경우 false를 원합니다. 하지만 람다 구문으로 표현하는 데 어려움을 겪고 있습니다.

내가 지금까지 (적어도 컴파일에서 작동하지 않지만있는)이있다 마련 할 수있었습니다 그 최고 :

DoSomething 입장에
boost::function<bool (size_t)> ge = boost::bind(std::greater_equal<size_t>(), 
               _1, threshold); 
boost::function<size_t()> size = boost::bind(&std::vector<std::string>::size, 
               data); 
DoSomething(boost::lambda::bind(ge, boost::lambda::bind(size)), other stuff); 

, 크기가 0 - 그리고 실행 중에 크기가 증가하더라도 condition()에 대한 호출은 항상 0 크기를 갖는 것처럼 보입니다. 부스트의 내부를 통해 다소 까다로운 부분이 있지만, 각각 greater_equal을 호출하는 것처럼 보입니다 condition() 시간이 계산되면 size()을 호출하지 않는 것 같습니다.

그래서 어떤 근본적인 것이 완전히 엉망이 되었습니까? 이런 종류의 것을 표현하는 더 간단한 방법이 있습니까? (가능한 한 코드를 인라인으로 유지하면서)?

내가 이상적으로 C# 동등한 코드를 유창에 가능한 한 가까이 싶습니다

DoSomething(delegate() { return data.size() >= threshold; }, other stuff); 
DoSomething(() => (data.size() >= threshold), other stuff); 

답변

5

문제는 람다 함수는 data 벡터의 사본이 아니라 참조를 저장한다는 것이다. 따라서 size()은 수정중인 원본 개체가 아니라 복사본에서 호출됩니다.

boost::function<size_t()> size = boost::bind(&std::vector<std::string>::size, 
               boost::ref(data)); 

당신은 또한 람다 함수의 정의에 대신 std::greater_equal<>의 정상적인 >= 연산자를 사용하고 모두 함께 결합 할 수 있습니다 :

을이 대신 참조를 저장 boost::refdata을 포장하여 해결할 수 있습니다
boost::function<bool()> cond = 
    (boost::bind(&std::vector<std::string>::size, boost::ref(data)) 
     >= threshold); 

DoSomething(cond, other stuff); 
+0

감사합니다. 나에게 놀랍지 만, 바운드 함수에> = 이와 같이 적용 할 수있다. 특히 람다 바인드가 아니기 때문에 그렇다. :) – Miral

+0

> =은 함수 객체에 오버로드되어 있지만 어쨌든 boost :: lambda :: bind가 더 나은 선택이 될 수 있습니다 ... – sth