为什么"std::vector<std::string> &"而不是"void"?
Why "std::vector<std::string> &" instead of "void"?
我想使用字符串拆分函数来回答这个问题的最高评分:
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
那有什么区别呢?
返回引用允许将调用split()
用作另一个函数的参数。 例如,假设我们有一些其他函数通过引用接受字符串向量
void func(std::vector<std::string> &elements);
如果 split()
返回引用,则可以将其返回的引用直接传递给 func()
。
func(split(s, delim, elems));
然而,如果split()
没有返回引用,则有必要这样做
split(s,delim, elems);
func(elems);
如果split()
返回引用,第二种使用方法仍然有效。
这两者之间的区别纯粹是程序员的方便,但很多程序员更喜欢使用第一种调用方式。 返回引用并不是一个特别昂贵的操作,因此允许程序员选择如何使用它不会损失太多。
语法糖使函数更加灵活。
通过示例:您可以编写
std::cout << "there are " << split(str, delim, vect).size() << " elemementsn";
对于void
假设情况,您需要 2 个语句。
您发布的示例没有区别。
但是,如果您想将其分配给另一个变量和/或将其传递给函数,则可能会有。
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
写 2 行。所以基本上是唯一的区别。
就结果而言,这两种方法之间完全没有区别。
但是,选项 1 清楚地表明函数multA
具有计算结果并返回该结果。
n1 = multA(n1);
另一方面,第二种选择不像第一种那样不言自明。通过阅读以下代码,您无法轻松判断multB
正在做什么。multB
可能只是用std::cout
记录结果。但是不阅读函数定义就无法分辨。
multB(n2);
- 库函数需要一个 std::function<void(void)>,如何传入类函数?
- <Windows>为什么 std::thread::native_handle 返回类型为"long long unsigned int"的值,而不是 void*(又名 HANDLE)?
- 如何在向量中删除 std::function<void()>?
- std::function<void()> 接受参数
- <char> 使用 Vulkan 映射内存时如何使用 std::vector 而不是 void**?
- std::bind to void* to std::function
- C++ 类型的参数与 void (__cdecl*)(void) 类型的参数不兼容,当调用 std::atexit()
- 我可以传递 &std::array<> 作为 void* 吗?
- 错误:"cast"未命名类型void setCastDescription(std::string
- 在c++std::函数的上下文中无效使用void表达式
- 如何将 std::string 作为构造函数参数传递,并将其保存的 C 字符串存储在 void 指针中?
- 如何将 std::string 赋回作为 <char>void* 指针传递的 std::vector.data()?
- 使用 void 函数作为回调,从 "std::function<void ()>?
- 无法初始化 libsupc++ 库中类型为 'std::terminate_handler' 的变量(又名 'void (*)()')
- 带有 std::map 的模板函数给出错误:变量或字段声明为 void
- reinterpret_cast std::function* to and from void*
- 从 'void *' 转换为 'const std::string *&' 必须具有所有中间指针 const 合格
- 为什么我们可以使用空括号来初始化 std::function<void(Node*)>离开?
- 我可以将函数指针 void* 强制转换为 std::function 吗?
- 将指针传递给 std::function<void()>