3

我最近看到以下代码块作为对这个问题的回应: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 函数,或者返回一个整数来表示成功/失败吗?无论如何,我们正在编辑实际的数组,对吧?

谢谢!

4

2 回答 2

6

通过返回对您传入的对象的引用,您可以在一个表达式中进行一些链接级联,并始终使用同一个向量。有些人觉得这很方便: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";
于 2012-07-18T17:56:32.877 回答
1

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

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

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

它将执行该函数并允许您通过调用向量上的函数来链接结果(在这种情况下size

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

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

于 2012-07-18T18:25:32.980 回答