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<void()>
替换为 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 崩溃的主要内容,如果未能解决你的问题,请参考以下文章
c++ std::bind 如何返回分配给 std::function 的值?