首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++11 std::bind的链接调用不起作用

C++11 std::bind的链接调用不起作用
EN

Stack Overflow用户
提问于 2012-08-20 17:48:25
回答 1查看 838关注 0票数 5

在调用嵌套的std::bind表达式时遇到问题。下面的代码演示了这个问题。它无法使用libc++编译,但可以使用boost:

代码语言:javascript
复制
#define BOOST 0

#if BOOST
    #include <boost/function.hpp>
    #include <boost/bind.hpp>
    using boost::function;
    using boost::bind;
#else
    #include <functional>
    using std::function;
    using std::bind;
    using std::placeholders::_1;
#endif


int sum(int a, int b) { return a+b; }

// works
template <typename F>
int yeah(F f, int c)
{
    return f(c);
}

// breaks with libc++
template <typename F>
int nope(F f, int c)
{
    return bind(f, c)();
}

// fixes the problem
template <typename F>
int fix1(F f, int c)
{
    function<int(int)> g = f;
    return bind(g, c)();
}

template <typename F>
class protect_t
{
public:
    typedef typename F::result_type result_type;

    explicit protect_t(F f): f_(f) {}

    template <typename... Args>
    result_type operator()(Args&&... args)
    {
        return f_(std::forward<Args>(args)...);
    }

private:
    F f_;
};

template <typename F>
protect_t<F> protect(F f)
{
    return protect_t<F>(f);
}

// compilation fails with libc++
template <typename F>
int fix2(F f, int c)
{
    return bind(protect(f), c)();
    // F copy(f);    // fails due to this!
}

#include <iostream>

int main()
{    
    std::cout << yeah(bind(sum, _1, 4), 5) << std::endl;  // works
    std::cout << nope(bind(sum, _1, 4), 5) << std::endl;  // breaks
    std::cout << fix1(bind(sum, _1, 4), 5) << std::endl;  // fixes
    std::cout << fix2(bind(sum, _1, 4), 5) << std::endl;  // doesn't compile
}

将绑定表达式包装在std::function (请参阅fix1)中可以解决这个问题,尽管由于运行时多态禁用内联而牺牲了速度(还没有对其进行测量)。

protect_t (请参阅fix2)中包装绑定表达式的灵感来自于boost::protect,但是,由于绑定表达式不可复制,使用libc++编译会失败。这让我想知道为什么把它们包装在std::function中是可行的。

你知道怎么解决这个问题吗?不管怎么说,std::bind怎么了?首先,我认为这个问题与C++11标准(请参阅here)规定的绑定表达式的急切计算有关,但这在这里不是问题,不是吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-09-30 17:43:01

该标准规定,任何可调用的对象都可以使用std::bind进行包装,包括前面对std::bind的调用所产生的可调用对象。您的问题是由您正在使用的标准库的实现中的缺陷引起的,解决方案是升级,或者,如果此错误仍未修复,则切换到不同的实现。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12035493

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档