如何存储std::bind绑定成员函数指针返回的可调用对象及编译错误分析
问题解答
问题1:为什么不存储std::bind返回值可正常编译,用auto存储就触发报错?
你遇到的是GCC内部编译器错误(ICE),属于编译器本身的缺陷,并非你的代码存在语法或语义错误:
- 当你将
std::bind的返回值直接作为std::find_if的入参传递时,属于纯右值临时对象直接传递给函数参数的场景,C标准允许(C17及以后强制要求)编译器执行返回值优化(RVO),直接将std::bind生成的临时对象构造在函数参数的内存位置,不需要调用该匿名可调用类型的拷贝/移动构造函数,也就不会触发编译器BUG。 - 当你用
auto fn2 =接收返回值时,若禁用了拷贝消除优化,编译器必须为该场景生成可调用对象的移动/拷贝构造逻辑。你使用的GCC版本恰好存在缺陷:仅在处理绑定了成员函数指针的std::bind返回类型的移动/拷贝构造代码生成时,会触发编译器自身的段错误,最终导致编译失败,这也是你绑定普通函数foo的fn变量可以正常编译的原因。
问题2:该报错是否和拷贝消除优化有关?
两者直接相关:
- 拷贝消除优化默认开启时,
auto fn2 = std::bind(...)场景下的移动/拷贝构造调用会被直接优化掉,不会触发GCC的该BUG,所以你直接在终端执行编译命令、以及移除-fno-elide-constructors选项后都可以正常编译运行。 - 你额外添加了
-fno-elide-constructors选项禁用拷贝消除后,编译器必须生成原本被优化掉的移动/拷贝构造代码,刚好命中GCC的该缺陷,才出现了内部编译错误。
内容的提问来源于stack exchange,提问作者Itachi Uchiwa
相关产品推荐
相关产品推荐

