【问题标题】:Utility of returning a vector by reference that was passed by reference通过引用返回通过引用传递的向量的实用程序
【发布时间】:2012-07-17 20:18:16
【问题描述】:

我最近看到以下代码块作为对这个问题的回应:Split a string in C++?

std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string>     
&elems) {
    std::stringstream ss(s);
    std::string item;
    while(std::getline(ss, item, delim)) {
        elems.push_back(item);
    }
    return elems;
}

为什么在这里返回通过引用传递的数组“elems”如此重要?我们不能把它变成一个 void 函数,或者返回一个整数来表示成功/失败吗?无论如何,我们正在编辑实际的数组,对吧?

谢谢!

【问题讨论】:

  • 它实际上是通过引用返回向量,而不是内存地址。
  • @Ben Decato 仅供参考:如果您查看 > 运算符重载(任何地方)的实现,您会看到这样的链接。这些运算符接收一个流并返回对同一流的引用,因此您可以执行诸如 std::cout
  • 谢谢——我编辑了帖子的标题以反映这一新发现的知识。

标签: c++ string vector pass-by-reference


【解决方案1】:

通过返回对您传入的对象的引用,您可以在一个表达式中执行一些链接级联,并始终使用同一个向量。有些人觉得这很方便:IE

  std::vector<std::string> elems;
  std::cout << "Number of items:" << split("foo.cat.dog", '.', elems).size();

  // get just foo
  std::cout << "First item is:" << split("foo.cat.dog", '.', elems)[0];

  // change first item to bar
  split("foo.cat.dog", '.', elems)[0] = "bar";

【讨论】:

    【解决方案2】:

    它不是返回内存地址,它实际上是通过非常量引用返回对象。传入的方式相同。这似乎有点矫枉过正,因为调用代码可以依赖于传递的第三个参数,该参数将在函数返回时填充,或者返回参数。

    这样做的原因是允许链接。所以你可以这样做:

    split(myString, ',', asAVector).size().
    

    它将执行该函数并允许您通过调用向量上的函数来链接结果(在本例中为size

    尽管简洁,但这种方法有一些潜在的缺点:例如,返回值中不存在错误代码,因此您依赖于函数正常工作或抛出异常;因此,您通常希望用 try / catch 语义来包装上面的内容。当然,你做的链接越多,出现不同类型异常的可能性就越大,因此你可能需要覆盖更多的catch 块。

    请注意,通过引用传回比通过指针传回要好得多。当链中的某个函数决定失败并返回 0 时,使用指针进行链接会因崩溃而臭名昭著。

    【讨论】:

      猜你喜欢
      • 2013-07-07
      • 2011-03-14
      • 1970-01-01
      • 1970-01-01
      • 2018-07-27
      • 2012-08-31
      • 1970-01-01
      相关资源
      最近更新 更多