2011-10-02 9 views
2

boost에 익숙해 지려고 시도하는 동안 std::vector과 함께 boost::function을 사용하는 데 문제가 발생했습니다. 간단한 일을하려고합니다 : similair 시그니처가있는 함수 목록을 가지고 샘플 데이터에 std::for_each과 함께 모든 함수를 사용하십시오. 여기에 코드입니다 : 내가 표준 출력에 데이터를 샘플링하기 위해 모든 기능을 적용한 결과를 작성하는 것을 시도하고 for_each에 따라서std :: vector <boost :: function> with boost :: bind

typedef boost::function<int (const char*)> text_processor; 
typedef std::vector<text_processor> text_processors; 
text_processors processors; 
processors.push_back(std::atoi); 
processors.push_back(std::strlen); 

const char data[] = "123"; 

std::for_each(processors.begin(), processors.end(), 
    std::cout << boost::bind(&text_processors::value_type::operator(), _1, data) 
       << "\n" 
); 

. 그러나 이렇게 컴파일되지 않습니다. bind 결과에 대해 누락 된 연산자 <<에 대한 긴 메시지가 표시됩니다.

스트림 연산자를 제거하면 컴파일 할 수 있지만 쓸모없는 코드가 생깁니다. 그 트릭은 기능 적용과 텍스트 출력을 하나의 for_each으로하고 싶다. 내가 뭘 놓치고 있니? lambdas 또는 smth와 같은 것이어야한다고 생각했지만 올바른 해결책을 찾아 내지 못했습니다.

답변

4

코드의 문제는 당신이 허용되지 않는 방법으로 장소에서 펑터를 만들려고한다는 것입니다 (방금 for_each의 세 번째 인수에 코드를 던질 수 없습니다, 당신은 에게 펑을 전달해야합니다). 당신이 std::transform보다는 std::for_each이 (테스트하지 ...하지만이 작동합니다)를 사용할 수 있습니다 컴파일러에서 람다 지원없이

:

std::transform(processors.begin(), processors.end(), 
       std::ostream_iterator<int>(std::cout, "\n"), 
       bind(&text_processors::value_type::operator(), _1, data)); 

컴파일러는 당신이 그것으로 할 수있는 람다 지원하는 경우 :

const char data[] = "123"; 
std::for_each(processors.begin(), processors.end(), 
    [&data](text_processors const &) { 
     std::cout << boost::bind(&text_processors::value_type::operator(), _1, data) 
       << "\n" 
    } 
); 

그런데 당신은 bind 모두 방지 할 수 있습니다

std::for_each(processors.begin(), processors.end(), 
       [&data](text_processors::value_type & op) { 
        std::cout << op(data) << "\n"; 
       } 
); 
+0

답장을 보내 주셔서 감사합니다. 'std :: transform'의 해결책은 트릭을 가져 오는 것 같습니다. 나는 두 개의 사실에 대해 머리를 감싸려고했다.'std :: cout << boost :: lambda :: _ 1 << ""n "은 functor이고 boost :: bind (...)는 다음과 같다. 펑터. 그러나 나는 그것을'std :: for_each'에 전달하기 위해 단일 펑터에서 결합 할 방법이 아직 없습니다. – elricbk

+0

나는 boost lambda 라이브러리를 사용하지 않았고 오랫동안 문서를 읽었지만 IIRC에는 필요한 라인에있을 수있는'boost :: lambda :: bind'가 있습니다. 다시 말하지만, 실제 경험이 없으면 마일리지가 다를 수 있습니다. –

관련 문제