【问题标题】:clang-tidy suggest I remove const references, why?clang-tidy 建议我删除 const 引用,为什么?
【发布时间】:2020-07-23 15:38:48
【问题描述】:

我在一个项目树上运行了 clang-tidy(“现代化”模块),我一直在努力使 C++17 保持合理的最新状态。它纠正的几乎所有内容对我来说都不足为奇,除了一件事:它改变了所有这些类型的结构:

void foo(const std::string& str) {
}

.. 到这个:

void foo(std::string str) {
}

我不明白为什么。对我未经训练的眼睛来说,这意味着两件事:

  1. 它需要复制对象而不是仅仅传递一个引用。 (虽然我假设在某些情况下编译器可以推断出它可以在生成代码时只传递一个指针 - 但引用使其明确(恕我直言更好)。
  2. const 用于告诉函数体开发人员它不应该更改输入字符串,并且如果它需要修改字符串,它需要在某处存储自己的副本。

我确实看到了一个好处——通过将一个对象作为const 引用传递,它只是一个“删除常量”而不会被更改,所以我想按值传递可以解决这个问题。

为什么建议删除带有非 const 值传递的 const 引用?

【问题讨论】:

  • 在您的情况下,我将采用 std::string_view 而不是常量引用。对我来说, std::string_view 取代了对常量字符串引用的需求

标签: c++ c++17 clang-tidy


【解决方案1】:

here 给出的理由是

在语言中添加了移动语义,标准库更新为为许多类型添加了移动构造函数,现在有趣的是直接按值而不是通过 const 引用获取参数,然后复制。此检查允许编译器负责选择构建副本的最佳方式。

另外

当调用代码传递一个右值并假设移动构造是一个廉价的操作时,转换通常是有益的。

但是,文档指出,唯一的替换是在以下特定情况下:

替换复制到类字段中的 const-references 构造函数参数的使用。然后使用 std::move() 移动参数。

如果多次使用构造函数参数,它甚至不会应用转换。

所以我认为所有你的函数不应该像那样被转换。

【讨论】:

  • 你是对的——它并没有改变所有这些;太多了,我以为是全部。
  • 请注意,clang-tidy 很棒,但您应该始终仔细检查转换以确保它们不会破坏任何东西。最好的方法是进行大量的测试:)
  • 是的——我运行了一堆现代化模块,运行了所有的单元测试、功能测试和系统测试,它们都通过了。我真的很惊喜。也就是说,我还不敢做任何事情。到目前为止,测试仅在一个平台上运行。
  • 哈,我知道这种感觉。但是如果你有一堆测试,那就太好了。大胆点,去吧:)
猜你喜欢
  • 1970-01-01
  • 2021-07-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-09
相关资源
最近更新 更多