特殊情况是,经过大规模重构后,一位同事改变了
Foo & foo = DoSomething();
到
auto foo = DoSomething();
,其中
Foo & DoSomething();
这导致了一个问题,即foo是通过副本而不是通过引用分配的。我们抓了一个案子。我很好奇是否有编译器警告来检测上述代码导致的错误类型。
**编辑**
以下所有答案都包含有关应该或不应该做的有用且有效的建议。为了清楚起见,我正在寻找一些关于在损坏发生后可以做些什么的建议。一个很少使用的编译警告会很好。最后,我们只检查了代码差异,看看是否多次犯了同样的错误。
答案 0 :(得分:1)
auto
的错误使用对性能非常不利。我已经开始讨论它的用法。
我的经验法则是尽可能使用auto &&
变量。这遵循模板规则并成为转发参考。
它可以用于引用,const引用和按值返回。
通过将此作为默认设置,auto
和auto &
清楚地表明您需要副本,或者您想要一个可变引用。
那就是说,我不熟悉这种结构的编译器警告。我确实找到了一个看似相似的铿锵有力的支票:https://clang.llvm.org/extra/clang-tidy/checks/performance-unnecessary-copy-initialization.html
答案 1 :(得分:0)
你的同事是一个非常顽皮的男孩。首先请注意,Visual C ++ 2013是不是 C ++ 11编译器,尽管它确实实现了一些C ++ 11标准。值得注意的是,constexpr
缺失。
非正式地说,auto
不自动包含&
,因此它们实质上已更改
Foo & foo = DoSomething();
到
Foo foo = DoSomething();
这体现了错误重构的危险,但没有进行适当的单元测试。
这里要做的正确的事情是保持代码不变。但是,如果你公司的文化是如此,所有新的和有光泽的东西必须进入一个项目,那么最好的事情是使用
auto&& foo = DoSomething();
要生成一次性的编译器警告,为什么不(暂时)删除复制构造函数并尝试构建项目?:
Foo(const Foo&) = delete;
答案 2 :(得分:-1)
一个好的经验法则可能是使用decltype(auto)
代替auto
并在心理上训练自己。
在提供的示例中,它会使foo
的类型成为对Foo
的引用。