2010-11-29 32 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) 
    ] 
);