std::bind 与 std::function 与 Clang 崩溃

Posted

技术标签:

【中文标题】std::bind 与 std::function 与 Clang 崩溃【英文标题】:std::bind to a std::function crashes with Clang 【发布时间】:2013-11-20 13:43:36 【问题描述】:

在将 std::bind 与 std::function 结合使用时,我无法理解一些微妙之处。

我已将我的问题最小化为以下代码 sn-p:

#include <functional>
#include <iostream>

void bar(int x) 
    std::cout << "Hello." << std::endl;


int main(int argc, char* argv[])

    std::function<void(int)> f1 = std::bind(bar, std::placeholders::_1);

    // CRASHES with clang, works fine in VS2010 and VS2012
    std::function<void()> f2 = std::bind(f1, 1);

    f2();

    return 0;

注意到 std::function 的显式转换(在构造 f2 时将 std::function&lt;void()&gt; 替换为 auto 可以正常工作)。

通过复制f1 对象来创建f2 在 OS X(XCode 5.0.1、OS X 10.9 SDK)上使用 Clang 会崩溃,但在 VS2010/VS2012 上运行良好。在一个长得可怕的调用堆栈之后,代码崩溃并出现 EXC_BAD_ACCESS - 注意这是在构造函数对象时,而不是在调用它时。

这是库实现中的错误还是我的代码有问题?

一种解决方法是显式调用operator () 成员,如下所示:

std::function<void()> f2 =
    std::bind(&std::function<void(int)>::operator(), f1, 1);

但这有一个警告,因为它无法在 VS2012 上编译(但在 VS2010 中有效)。这似乎是a bug with VS2012。

【问题讨论】:

一个相关的问题好像是***.com/q/19820128/227322。 【参考方案1】:

您的代码适用于 clang 3.4(主干,194324)。它也适用于 gcc 4.7.2。

-Wall -Wextra -pedantic 没有收到任何警告(除了那些抱怨未使用的 x、argc 和 argv 参数的警告)。

过去,clang 实现似乎有问题,但已经修复。

【讨论】:

你说得对,升级到 Xcode 5.0.2 似乎可以解决问题。 @villintehaspam 很高兴听到这个消息! 请注意,从 App Store 下载的 XCode 5.0.2 与从 developer.apple.com 下载的 XCode 5.0.2 之间似乎存在某种差异。它适用于从 dev 下载的版本,但不适用于从 App Store 下载的版本。 很遗憾,我没有 Mac,所以...它们的版本号是否完全相同?也许它工作的那个稍微更新一些。 (我只是猜测。)

以上是关于std::bind 与 std::function 与 Clang 崩溃的主要内容,如果未能解决你的问题,请参考以下文章

std::function与std::bind

std::function与std::bind

std::function与std::bind使用总结

c++ std::bind 如何返回分配给 std::function 的值?

C++11 std::bind函数,std::function函数

C++11新特性应用--实现延时求值(std::function和std::bind)