通过引用传递std :: string_view

时间:2019-10-16 10:08:26

标签: c++ c++17

最近,在代码审查期间,我偶然发现了引用传递的std::string_view参数。因此,例如以下代码:

void fun(std::string_view a);

成为

void fun(std::string_view& a);

由于以下原因,我发现它很麻烦:

  • l-value std::string_view之外,不能再使用它。
  • 使用std::string_view的全部意义在于避免复制基础字符串,因此我认为没有必要使用&

问题是,将std::string_view参数声明为通过引用传递而不是通过值传递有什么好处吗?

1 个答案:

答案 0 :(得分:0)

这个问题有点不清楚,因为两者在语义上有很大不同。

传递非常量引用意味着按参数返回-即您可以在某个时候修改函数内部的值,并且可以使用或不使用原始输入值。因为您只能将string_view指向其他内容,并且不允许修改内容。因此,我应该期待以下内容-该函数将输入string_view用于某些内容,然后将该输入strint_view指向其他内容。语义上的改进将是:

  void fun(std::string_view& a);

改进版本:

 std::string_view fun(const std::string_view& a);

(语义上)更好的解决方案:

 std::string_view fun(std::string_view a);

现在,提供输入内容更加容易,如果我想重新输入输入string_view,我可以选择自己。


除此以外,由于以下原因,本参考文献处于不利地位:

  • 语义上的副本更好:对副本进行推理比 引用(甚至是const引用)。
  • 如果还要考虑性能,则参考标记为 在大多数情况下都是不利的,充其量看起来只能与副本大致相同。使用clang进行演示:https://godbolt.org/z/UR68km(结果可能因编译器而异)

请注意,即使复印件变慢了一点点-它仍然应该是首选的通过方法。


在编写函数时,我通常会使用以下助记符:

  

通过 const 引用传递,按值返回。 除非可以,否则通过   按值代替。

在这里很合适。您可以可以的时间包括何时不涉及潜在的大数据副本,并且在这种情况下(某些情况下,引用是唯一的选择)。使用此经验法则可确保您不会意外地制作多余的 large 数据副本 。除标量外,应按值传递的最值得注意的类类型是属于 proxy 类别的那些类型(例如,智能指针和视图)。

您很少应该通过非常量引用进行传递-通常情况是修改缓冲区时。指针在某种程度上也是如此。