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

std::bind绑定std::shared_ptr::operator*在MSVC编译失败,是bug还是可修复?

问题

以下C代码可在g 8.1.0和clang 10.0.0环境下正常编译:

#include <memory>
#include <iostream>
#include <functional>

int main() {
    auto dereference = std::bind(
        &std::shared_ptr<int>::operator*,
        std::placeholders::_1);

    std::shared_ptr<int> sp = std::make_shared<int>(10);
    std::cout << dereference(sp) << std::endl;

    return 0;
}

但在VS2022的MSVC编译器中,会报出如下错误:

example.cpp<source>(6): error C2672: 'std::bind': no matching overloaded function found
C:/data/msvc/14.34.31931-Pre/include\functional(2029): note: could be 'std::_Binder<_Ret,_Fx,_Types...> std::bind(_Fx &&,_Types &&...)'
<source>(8): note: 'std::_Binder<_Ret,_Fx,_Types...> std::bind(_Fx &&,_Types &&...)': could not deduce template argument for '_Ret'
<source>(8): note: 'std::_Binder<_Ret,_Fx,_Types...> std::bind(_Fx &&,_Types &&...)': could not deduce template argument for '_Fx'
C:/data/msvc/14.34.31931-Pre/include\functional(2024): note: or       'std::_Binder<std::_Unforced,_Fx,_Types...> std::bind(_Fx &&,_Types &&...)'
<source>(8): note: 'std::_Binder<std::_Unforced,_Fx,_Types...> std::bind(_Fx &&,_Types &&...)': could not deduce template argument for '_Fx'
<source>(11): error C3536: 'dereference': cannot be used before it is initialized
<source>(11): error C2064: term does not evaluate to a function taking 1 arguments
Compiler returned: 2

请问这是MSVC编译器的bug,还是上述代码可以修复?

解答

这不是MSVC的bug,代码可以修复。问题出在std::shared_ptr<int>::operator*的重载上——这个成员函数有const和非const两个版本,当直接取地址&std::shared_ptr<int>::operator*时,MSVC无法自动推导要绑定的是哪个重载版本,而GCC和Clang在这种场景下做了额外的推导兼容。

修复方法有两种:

  • 显式指定重载版本的类型:通过强制类型转换明确告诉编译器要绑定的是哪个版本的operator*,通常选择const版本适用性更广:
auto dereference = std::bind(
    static_cast<int& (std::shared_ptr<int>::*)() const>(&std::shared_ptr<int>::operator*),
    std::placeholders::_1);
  • 改用lambda表达式替代std::bind:lambda的可读性和兼容性更好,完全避免重载推导问题,还能简化代码:
auto dereference = [](const std::shared_ptr<int>& sp) -> int& {
    return *sp;
};

或者更通用的版本:

auto dereference = [](const auto& sp) -> decltype(auto) {
    return *sp;
};

内容的提问来源于stack exchange,提问作者syby119

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 05:01:26