为什么使用“std::vector<std::string>&”而不是“void”?

3
我想使用最高评分答案中的字符串拆分函数,该问题的链接如下:Split a string in C++?。以下是方便复制的回答:
#include <string>
#include <sstream>
#include <vector>

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;
}


std::vector<std::string> split(const std::string &s, char delim) {
    std::vector<std::string> elems;
    split(s, delim, elems);
    return elems;
}

我在这里有一个问题。为什么声明是std::vector<std::string> &split(...)而不是void split(...)?作为参数,我们接收std::vector<std::string> &elems,这就是我们想要的结果。如果我们接收到一个引用,为什么还需要返回任何东西呢?
我有:
int &multA (int &n)
{
    n = 5*n;
    return n;
}

void multB (int &n)
{
    n = 5*n;
}

并且:

int n1, n2;
n1 = 1;
n2 = 1;
cout << "n1: " << n1 << endl;
cout << "n2: " << n2 << endl;
n1 = multA(n1);
multB(n2);
cout << "n1: " << n1 << endl;
cout << "n2: " << n2 << endl;

结果,我有:

n1: 1
n2: 1
n1: 5
n2: 5

那么有什么区别呢?

2
如果需要,它只是一个便利,让您可以将返回值用作lvalue。 - Aenimated1
它应该与内存管理有关。 - polfosol ఠ_ఠ
4个回答

5

返回一个引用允许将split()的调用用作另一个函数的参数。例如,假设我们有一些其他函数,通过引用接受字符串向量。

  void func(std::vector<std::string> &elements);

如果split()返回一个引用,则可以直接将其返回的引用传递给func()
  func(split(s, delim, elems));

如果split()不返回引用,则需要执行以下操作:

  split(s,delim, elems);
  func(elems);

第二种用法仍然有效,如果split()返回一个引用。
这两种方法的区别纯粹是程序员的方便,但很多程序员更喜欢使用第一种调用风格。返回一个引用不是特别昂贵的操作,所以允许程序员在如何使用它方面有选择并不会失去太多。

3

这是一种语法糖,使函数更加灵活。

比如说:你可以这样写

std::cout << "there are " << split(str, delim, vect).size() << " elemements\n";

使用“void”假设的情况下,需要两个语句。

1
使用“语句”这个词比使用“指令”更加准确。 - Peter
@ Peter - 谢谢;我不是母语为英语的人,所以经常使用不正确的术语(也许我的语言也有错误);我更正了我的回答。 - max66
1
没问题,但你的英文回答很好(现在也是)。 “语句”这个词在C ++中有特定的含义。 在计算机科学中,“指令”(在此上下文中)具有与C ++中的语句不同的特定含义。 你给出的代码示例是单个C ++语句。 - Peter

1
你所发布的示例没有区别。
但是,如果你想将其分配给另一个变量和/或传递给函数,则可能会有区别。
int a = multA(n1); //In one line :)
foo(multA(na1));   //Same thing, one line only

multB(n1);
int a = n1; //Two lines

multB(n1);
foo(n1);    //Two lines

这里 multA 明显更好,因为你可以用一行代码来写它,而不是用 multB 的两行。所以基本上唯一的区别就是这样。


0
就结果而言,这两种方法没有任何区别。
然而,选项1清楚地表明函数multA具有计算结果,并返回该结果。
n1 = multA(n1);

另一方面,第二个选项并不像第一个选项那样自解释。通过阅读以下代码,您无法轻易地了解multB正在做什么。可能multB只是使用std::cout记录结果。但是如果没有阅读函数定义,您就无法确定。
multB(n2);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接