VS15中std::bind实例化std::function标红但可编译问题咨询
问题背景
- 实例化元素类型为
std::vector<std::pair<std::function<bool()>, std::function<void(int)>>>的容器时,Visual Studio 15编辑器出现红色下划线警告,但代码可正常编译通过。 - 基础场景下使用
std::bind返回值初始化std::function,同样存在「可正常编译但编辑器标错」的现象。 - 已知
std::bind返回值类型并非std::function,但公开资料中存在大量同写法的std::function实例化示例,需要确认该写法是否存在潜在故障,还是属于Visual Studio误报。


复现代码
#include <functional> #include <vector> // 原复现代码遗漏<iostream>头文件,实际编译使用std::cout需补充引入 #include <iostream> class A { public: bool myFunc() { return false; }; void myDoFunc(int x) { std::cout << "HiXXX"; }; class Seq{ public: std::vector<std::pair<std::function<bool()>, std::function<void(int)>>> sequencePieces; const char* name; Seq(const char* _name, std::vector<std::pair<std::function<bool()>, std::function<void(int)>>> _sequencePieces): name(_name), sequencePieces(_sequencePieces) {} }; std::function<bool()> sequenceStep; Seq seq1; A() : seq1( "ASDF", { /*Error 1 编辑器标红位置*/ std::pair<std::function<bool()>, std::function<void(int)>>( std::bind(&A::myFunc,this), std::bind(&A::myDoFunc, this, 1) ) } ) { /*Error 2 编辑器标红位置*/ sequenceStep = std::bind(&A::myFunc, *this); }; };
结论
这是Visual Studio 15(2017版本)IntelliSense的已知误报,对应写法完全符合C++标准,不存在潜在故障隐患。
std::function的构造、赋值运算符按C++标准要求,支持隐式转换所有调用签名匹配的可调用对象。std::bind返回的仿函数只要入参、返回值与std::function的模板参数定义匹配,就可以合法用于初始化、赋值std::function实例,公开场景中大量同类写法均为合规实现。- Visual Studio 2017的IntelliSense采用独立于MSVC编译器的EDG解析前端,对嵌套层级较深的复杂模板、
std::bind这类返回实现定义类型的可调用对象存在模板参数推导缺陷,会在编辑器中抛出假阳性错误提示,该提示仅存在于编辑器静态检查阶段,完全不影响实际编译与运行结果。
消除编辑器标红的可选方案
如果需要规避红色下划线的开发干扰,可选择以下任意方案,所有方案均不改变代码实际运行逻辑:
- 升级Visual Studio至2019及以上版本,新版IntelliSense引擎已修复该类模板推导导致的假阳性问题。
- 对
std::bind返回值做显式std::function类型构造,明确指定目标类型,辅助IntelliSense完成类型推导:例如将构造场景中的std::bind(&A::myFunc,this)替换为std::function<bool()>(std::bind(&A::myFunc,this)),赋值场景处理逻辑一致。 - 在Visual Studio文本编辑器设置中,关闭对应错误编号的IntelliSense错误提示。
内容的提问来源于stack exchange,提问作者StephBoyardee
相关产品推荐
相关产品推荐

