类成员移动可能抛异常时,是否仍需为移动构造函数声明noexcept?
关于MSVC C26439警告的处理方案
先给准话:不能随便加noexcept
C++核心准则f.6的要求是**“确定函数不会抛异常”才加noexcept**,不是不管三七二十一强制加。如果你的移动构造函数里调用的成员操作(比如cv::Mat的移动)可能抛异常,或者你拿不准,那绝对不能加noexcept——不然真出异常的时候,程序会直接终止,比异常本身还麻烦。
具体说你的情况
- OpenCV的
cv::Mat没给准信:它的移动/复制构造函数没标noexcept,就意味着官方没承诺这个操作不会抛异常。而且你还要适配不同版本,旧版本甚至连移动构造都没有,这时候std::move会直接退化成复制,风险更大。 - MSVC的警告只是建议:这个C26439是静态分析提示,它只看到你的移动构造函数里没做复杂操作,但不知道
cv::Mat的底细。你比编译器清楚实际依赖的库情况,所以可以无视这个提示。
怎么处理?
- 直接屏蔽警告:要么在项目设置里关掉C26439,要么在代码里局部屏蔽:
#pragma warning(push) #pragma warning(disable: 26439) MyClass(MyClass&& other) : mat{ std::move(other.mat) } { } #pragma warning(pop) - 按OpenCV版本适配:如果你能查到某个版本的
cv::Mat移动确实不会抛,可以针对性加noexcept:#if (CV_VERSION_MAJOR >= 4) && defined(CV_HAVE_RVALUE_REFS) // 确认4.x及以上版本Mat移动无异常才加 MyClass(MyClass&& other) noexcept : mat{ std::move(other.mat) } { } #else // 旧版本不标记noexcept MyClass(MyClass&& other) : mat{ std::move(other.mat) } { } #endif - 换个方式封装:如果非要满足准则,用
std::unique_ptr包一层cv::Mat,因为智能指针的移动是noexcept的,但这会增加代码复杂度,没必要的话别折腾。
内容的提问来源于stack exchange,提问作者mentalmushroom
相关产品推荐
相关产品推荐

