【问题标题】:cannot convert boost::lambda::placeholder1_type无法转换 boost::lambda::placeholder1_type
【发布时间】:2014-05-12 11:15:17
【问题描述】:

我正在尝试使用 boost::lambda,但遇到了一个错误,我无法弄清楚如何解决。

我觉得这是一个初学者的错误,所以请原谅我的无知(而且,我不得不承认,我懒惰没有阅读整个 boost lamda 文档)。

似乎在某些情况下使用 boost::bind(或者可能是 boost::lambda::bind?)比 boost::lambda 更适合,但我不确定它是否可以在这里应用。我不想为if cond(arg1) arg2.insert(arg1) ; 编写单独的函数,因为它会破坏目的;我猜它不会比函子好多少。

我在工作中使用带有 VC9 的 boost 1.35。错误位于 cond()insert() 调用站点: "C2664: 无法从 'boost::lambda::placeholder1_type" 转换参数 1

我在我的 cygwin 上用 g++ 复制了这个 sn-p 的问题。

#include <boost/function.hpp>
#include <boost/lambda/bind.hpp>
#include <boost/lambda/if.hpp>

#include <boost/foreach.hpp>
#include <iostream>
#include <set>

void work(  boost::function<void(long)> doAction ) {
    long results[] = { 2, 5, 4 };
    BOOST_FOREACH( long r, results )
        doAction( r );
}

bool cond( long r ) { return r % 2 == 0 ; }

int main() {
    using namespace boost::lambda;
    std::set<long> myResults;
    work( 
        if_then( cond(_1) , boost::ref(myResults).get().insert(_1) ) );

    BOOST_FOREACH( long r, myResults )
        std::cout << r << "\n";
}

g++ 错误:

lambda_test.cpp: In function ‘int main()’:
lambda_test.cpp:21:19: error: cannot convert ‘boost::lambda::placeholder1_type {aka const boost::lambda::lambda_functor<boost::lambda::placeholder<1> >}’ to ‘long int’ for argument ‘1’ to ‘bool cond(long int)’
if_then( cond(_1) , boost::ref(myResults).get().insert(_1) ) );
               ^
lambda_test.cpp:21:60: error: no matching function for call to ‘std::set<long int>::insert(boost::lambda::placeholder1_type&)’
if_then( cond(_1) , boost::ref(myResults).get().insert(_1) ) );

任何帮助将不胜感激,

谢谢

【问题讨论】:

    标签: c++ boost boost-lambda


    【解决方案1】:

    您将延迟执行与立即评估混合在一起:

    boost::ref(myResults).get().insert(_1)
    

    这里,boost::ref(myResults) 并不懒惰,所以 .get() 也不是。 boost::ref(myResults).get() 的类型只是 std::set&lt;long&gt; &amp;,并且该类型的 insert 成员函数没有采用 Boost Lambda 占位符的重载。

    我不再精通 Boost Lambda,因为我已经转移到它的后继库 Boost Phoenix。这是带有修复的一对一翻译:Live On Coliru

    #include <boost/phoenix.hpp>
    
    #include <boost/foreach.hpp>
    #include <iostream>
    #include <set>
    
    template <typename Action>
    void work(  Action doAction ) {
        long results[] = { 2, 5, 4 };
        BOOST_FOREACH( long r, results )
            doAction( r );
    }
    
    bool cond( long r ) { return r % 2 == 0 ; }
    
    
    int main() {
        namespace phx = boost::phoenix;
        using namespace phx::placeholders;
    
        std::set<long> myResults;
        work( 
            if_(phx::bind(cond, _1)) [ phx::insert(phx::ref(myResults), _1) ] );
    
        BOOST_FOREACH( long r, myResults )
            std::cout << r << "\n";
    }
    

    打印

    2
    4
    

    我建议看一下 Phoenix 函数适配,以避免绑定表达式:

    【讨论】:

    • 感谢您的及时!不幸的是,我无法更新我们的 boost 版本,并且 boost::phoenix 不在 1.35 中(但是有一个 boost/spirit/phoenix.hpp)。请问我应该如何使用 boost 1.35 功能修复相同的代码?还有一点,我不明白我将延迟执行与立即评估混为一谈。由于有占位符,它如何立即评估?和lambda variables delay没有关系吧?
    • 您可以使用与#include &lt;boost/spirit/include/phoenix.hpp&gt; 相同的代码(也可以选择phoenix_statement.hpp)。 BOOST_PHOENIX_ADAPT_FUNCTION 届时将不可用
    • @unagi 关于“混淆”,我在答案中扩展了我的解释。我之前忘记了。
    • 确实!谢谢你的解释。
    • @unagi 我认为this 应该可以,但它真的很糟糕,也许sehe 会知道一种让它更“可口”的方法。 (添加链接使其更有用:))。 PS:This更好。
    猜你喜欢
    • 2017-12-09
    • 2019-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多