使用auto重新赋值std::bind:哪个编译器的实现符合标准?
std::bind返回对象赋值的编译器差异问题
以下代码可在MSVC中编译通过,但无法在GCC和Clang中编译:
#include <iostream> #include <functional> class Class { public: void display() { std::cout << "display" << std::endl; } void store() { std::cout << "store" << std::endl; } }; int main() { Class instance; // std::function<void(void)> f; // this will work auto f = std::bind(&Class::display, instance); f(); f = std::bind(&Class::store, instance); f(); }
问题分析
核心差异在于std::bind返回的未指定类型仿函数对象的拷贝赋值运算符:
- GCC和Clang的实现中,该对象的拷贝赋值运算符被显式删除(
= delete),因此无法执行f = std::bind(...)这类赋值操作。 - MSVC的实现则为该对象提供了拷贝赋值运算符,允许这类赋值行为。
标准角度的判断
C++标准仅规定:当绑定的所有参数都可拷贝时,std::bind返回的对象必须支持拷贝构造,但并未强制要求它必须支持拷贝赋值。
从标准规范的严谨性来看,GCC和Clang的实现更准确——它们严格遵循了标准的最低要求,没有提供标准未规定的额外行为。而MSVC的实现属于超出标准要求的扩展特性,虽能满足部分场景需求,但不符合标准的规范预期。
如果需要对绑定后的调用对象执行赋值操作,正确的做法是将其存储在std::function中(即代码中注释行的写法),std::function是标准明确规定支持拷贝赋值的通用函数包装器。
内容的提问来源于stack exchange,提问作者Thomas W.
相关产品推荐
相关产品推荐

