You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 23:24:41