VS2015编译器警告C4239咨询:非const引用默认实参问题
首先得明确警告的根源:你声明的默认实参shared_ptr<string>()是个临时对象(右值),而C++标准规定,非const的左值引用(也就是shared_ptr<string>&)是不能绑定右值的。VS2015的非标准扩展允许了这种操作,但同时抛出了C4239警告——哪怕你项目设置的是/W3,可能是VS2015的/W3规则包含了部分/W4的警告项。
下面是几个合法的解决思路,不需要调整原有功能:
方案1:将引用改为const引用(推荐,完全符合标准)
如果你的checkMe方法不需要修改传入的shared_ptr,直接把参数改成const shared_ptr<string>&即可。标准C++允许const左值引用绑定临时对象,完全合法,也不会触发警告:
void checkMe(const shared_ptr<string>& param = shared_ptr<string>());
这个方案最干净,也是C++中处理这类默认实参的常规写法,建议优先考虑。
方案2:使用静态左值作为默认实参(适合需要非const引用的场景)
如果你的方法必须要修改传入的shared_ptr(所以不能用const引用),那可以定义一个静态的空shared_ptr实例作为默认值。静态对象是左值,能合法绑定到非const左值引用:
// 放在匿名命名空间里,避免全局命名空间污染 namespace { static std::shared_ptr<std::string> empty_shared_ptr_default; } void checkMe(std::shared_ptr<std::string>& param = empty_shared_ptr_default);
静态对象的生命周期和程序一致,不用担心悬空问题,完全符合C++标准。
方案3:临时抑制警告(不推荐,仅作为兜底)
如果以上两种方案都无法满足你的需求,可以暂时用VS的编译指令抑制这个警告,但这只是绕过问题而非解决问题,建议谨慎使用:
#pragma warning(disable: 4239) void checkMe(std::shared_ptr<std::string>& param = std::shared_ptr<std::string>()); #pragma warning(default: 4239) // 恢复警告,避免影响其他代码段
内容的提问来源于stack exchange,提问作者da-chiller
相关产品推荐
相关产品推荐

