通过引用返回通过引用传递的向量的实用程序

Posted

技术标签:

【中文标题】通过引用返回通过引用传递的向量的实用程序【英文标题】: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 谢谢——我编辑了帖子的标题以反映这一新发现的知识。 【参考方案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 时,使用指针进行链接会因崩溃而臭名昭著。

【讨论】:

以上是关于通过引用返回通过引用传递的向量的实用程序的主要内容,如果未能解决你的问题,请参考以下文章

通过引用函数传递向量,但更改不会持续

通过引用传递向量内联

通过引用传递向量的 typedef 向量

C++:试图理解通过引用传递向量

通过引用传递向量然后调用清除

通过引用传递 - 左值和向量