如何消除deprecated-copy警告?C++代码改写可行方案咨询
问题描述
适配导入的大型代码库时,希望尽可能少修改代码。简化后的代码如下:
void function (object& out_thing) { object thing; #pragma omp nowait for (int k = 0 ; k < 5 ; k++) { object* things[2]; float scores[2]; for (i = 0; i < 2 ; i++) scores[i] = evaluateThings(things[i], parameter1, parameter2); if (scores[1] < scores[0]) { scores[0] = scores[1]; things[0] = things[1]; } thing = *(things[0]); } out_thing = thing; }
编译时因object存在用户自定义拷贝构造函数,thing = *(things[0])和out_thing = thing两处触发[-Wdeprecated-copy]废弃拷贝警告。尝试将object thing;改为指针方式(如object* thing = NULL)后仍有一处警告残留,寻求无需大幅修改代码、不影响性能的警告消除方案。
可行解决方案
方案1:局部禁用警告
针对触发警告的代码块临时禁用-Wdeprecated-copy,编译结束后恢复警告,既不影响全局编译严格性,也无需修改业务逻辑:
void function (object& out_thing) { object thing; #pragma omp nowait for (int k = 0 ; k < 5 ; k++) { object* things[2]; float scores[2]; for (i = 0; i < 2 ; i++) scores[i] = evaluateThings(things[i], parameter1, parameter2); if (scores[1] < scores[0]) { scores[0] = scores[1]; things[0] = things[1]; } // 临时禁用警告 #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-copy" thing = *(things[0]); #pragma GCC diagnostic pop } // 同样处理此处警告 #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-copy" out_thing = thing; #pragma GCC diagnostic pop }
注:如果使用Clang编译器,将GCC替换为Clang即可。
方案2:改用移动语义(如果object支持)
如果object类已经实现了移动赋值运算符(operator=(object&&)),可以通过std::move将拷贝转为移动,既消除警告,还可能提升性能:
// 替换两处赋值 thing = std::move(*(things[0])); // ... out_thing = std::move(thing);
这种方式无需修改代码结构,只是添加std::move调用,属于最小改动。
方案3:直接复用out_thing,避免中间变量
去掉局部变量thing,直接将结果赋值给out_thing,减少一次拷贝操作:
void function (object& out_thing) { #pragma omp nowait for (int k = 0 ; k < 5 ; k++) { object* things[2]; float scores[2]; for (i = 0; i < 2 ; i++) scores[i] = evaluateThings(things[i], parameter1, parameter2); if (scores[1] < scores[0]) { scores[0] = scores[1]; things[0] = things[1]; } // 临时禁用警告(如果需要)或用move #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-copy" out_thing = *(things[0]); #pragma GCC diagnostic pop } }
这种方式减少了一个中间变量,同时消除了一处拷贝警告,改动极小。
方案4:全局选择性禁用(不推荐,除非必要)
如果该类的拷贝警告在整个代码库中都无需关注,可以在编译选项中针对object所在的文件或类添加-Wno-deprecated-copy,但这种方式会放宽全局编译检查,仅建议在无法局部处理时使用。
内容的提问来源于stack exchange,提问作者Adrian K-B.
相关产品推荐
相关产品推荐

