2010-11-29 64 views
2

請看看下面簡單的例子:幫我打的boost ::拉姆達::表達if_then的調用一個函數對象

#include <vector> 
#include <string> 
#include <algorithm> 
#include <boost/lambda/lambda.hpp> 
#include <boost/lambda/bind.hpp> 
#include <boost/lambda/if.hpp> 

using namespace boost::lambda; 
namespace bl = boost::lambda; 

using namespace std; 

struct Item 
{ 
    string sachNr; 
    int ist; 
    int soll; 
}; 

struct Printer 
{ 
    void operator()(const Item &item) 
    { 
     m_erg += item.sachNr; 
    } 

    operator string() 
    { 
     return m_erg; 
    } 

private: 

    string m_erg; 
}; 

void TestFunction() 
{ 
    vector<Item> pickItems; 

    string result = for_each(pickItems.begin(), pickItems.end(), 
     bl::if_then(bl::bind(&Item::ist, bl::_1) == bl::bind(&Item::soll, bl::_1), 
     Printer())); 
} 

ERRORMESSAGE(GCC)

/TestCpp-build-desktop/../TestCpp/ctest.cpp:52: error: no matching function for call to ‘if_then(const boost::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::relational_action<boost::lambda::equal_action>, boost::tuples::tuple<boost::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::action<2, boost::lambda::function_action<2, boost::lambda::detail::unspecified> >, boost::tuples::tuple<int Item::* const, const boost::lambda::lambda_functor<boost::lambda::placeholder<1> >, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type> > >, boost::lambda::lambda_functor<boost::lambda::lambda_functor_base<boost::lambda::action<2, boost::lambda::function_action<2, boost::lambda::detail::unspecified> >, boost::tuples::tuple<int Item::* const, const boost::lambda::lambda_functor<boost::lambda::placeholder<1> >, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type> > >, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type, boost::tuples::null_type> > >, Printer)’ 

任何提示什麼是錯的用那個代碼?

它應該調用任何item.soll == item.ist項目的打印機仿函數。

感謝您的幫助!

+0

不知道這特別的錯誤,而是試圖用替代語法(`if_(條件)[功能]`揭示了另一個問題:對函子'的for_each `不是'Printer',而是一個boost lambda對象,因此你不能指望字符串的轉換髮生 - 因爲你已經寫了一個函數,爲什麼不讓它做更多的工作? – visitor 2010-11-29 14:06:04

回答

2

ronag是正確的,boost的lambda參考文件提到「他們都採取lambda仿函數作爲參數並返回void」。

似乎替代語法(bl::if_(condition)[function])不需要lambda函子。

但是,另一個大問題是for_each返回的函數是boost lambda對象,而不是您的打印機。因此無論如何您都無法檢索累積的字符串。

你可能會得到它與像這樣的工作:

#include <vector> 
#include <string> 
#include <algorithm> 
#include <boost/lambda/lambda.hpp> 
#include <boost/lambda/bind.hpp> 
#include <boost/lambda/if.hpp> 

using namespace boost::lambda; 
namespace bl = boost::lambda; 

using namespace std; 

struct Item 
{ 
    string sachNr; 
    int ist; 
    int soll; 
}; 

struct Printer 
{ 
    typedef void result_type; 
    void operator() (const Item &item, std::string& s) const 
    { 
     s += item.sachNr; 
    } 
}; 

void TestFunction() 
{ 
    vector<Item> pickItems; 

    string result; 
    for_each(pickItems.begin(), pickItems.end(), 
     bl::if_then(
      bl::bind(&Item::ist, bl::_1) == bl::bind(&Item::soll, bl::_1), 
      bl::bind(Printer(), bl::_1, boost::ref(result)) 
     ) 
    ); 
} 

然而,

void TestFunction() 
{ 
    vector<Item> pickItems; 
    string result; 
    BOOST_FOREACH(const Item& item, pickItems) { 
     if (item.ist == item.soll) 
      result += item.sachNr; 
    } 

} 

會有很多簡單的得到你想要的。 for_each幾乎沒有任何用處,所以我不會用我的方式來使用它,除了微不足道的事情。

1

試試這個:

Printer printer; 
std::for_each(pickItems.begin(), pickItems.end(), bl::if_then(bl::bind(&Item::ist, bl::_1) == bl::bind(&Item::soll, bl::_1), bl::bind(&Printer::operator(), &printer, bl::_1))); 

這在我看來,BL ::的if_then不接受任何仿函數,它需要一個lambda_functor。

1

已經提供了正確的答案。只是提供不涉及一個Printer對象的選擇:

std::string s; 
for_each(
    pickItems.begin(), pickItems.end(), 
    bl::if_ (bl::bind(&Item::ist, bl::_1) == bl::bind(&Item::soll, bl::_1)) 
    [ 
     s += bl::bind(&Item::sachNr, bl::_1) 
    ] 
);