[英]Get result into the caller from a function returning std::optional of std::vector
我正在尝试使用std::vector
之类的容器来操纵std::optional
。
我首先执行以下代码:
#include <iostream>
#include <vector>
#include <string>
#include <optional>
using namespace std;
using optional_vecs = std::optional<std::vector<std::string>>;
optional_vecs returnStrings()
{
optional_vecs myVect(std::in_place);
myVect->emplace_back("Name");
return myVect;
}
int main()
{
for (auto e : returnStrings().value())
std::cout << e << " ";
return 0;
}
这里的问题是我在输出中什么也得不到:我猜是因为std::optional::value
返回一个引用,因为在我的例子中它是对临时对象的引用。
所以为了解决这个问题,我尝试使用std::reference_wrapper
如下:
using optional_vecs = std::optional<std::reference_wrapper<std::vector<std::string>>>;
optional_vecs returnStrings()
{
optional_vecs myVect;
myVect->get().emplace_back("Name");
return myVect;
}
现在我遇到了崩溃和错误:
for-range
循环时说the range for loop requires a suitable "begin" function and none was found.
下面的代码有效,但我不喜欢声明一个变量然后调用 Value():
int main()
{
auto result = returnStrings();
for (auto e : result.value())
std::cout << e << " ";
return 0;
}
那么我怎么能返回一个 std::optional 以functionName().Value()
的方式持有一个std::vector
。
在前两种情况下,您的问题是,由于returnStrings()
返回一个临时值,除非您实际捕获它返回的内容,否则 for 循环不会延长其生命周期。 捕获result.value()
对你没有任何好处,因为它不会延长returnStrings()
的生命周期。
那么我怎么能返回一个 std::optional 以
functionName().Value()
的方式持有一个 std::vector 。
您必须捕获functionName()
的返回值。 你可以做你所做的,或者在 C++20 中,你可以使用 ranged for 的新init-statement版本,它是为这样的情况构建的,看起来像
for (auto&& opt_vec = returnStrings(); auto e : opt_vec.value())
std::cout << e << " ";
不幸的是,您必须使用后一种构造。
optional
对象负责拥有vector
。 C++ 不会递归地将生命周期延长到拥有被引用对象的对象,因此如果拥有对象被销毁(它会被销毁,因为它是临时的),被引用对象也将被销毁。
不过我要指出一件事:至少就 GCC 而言,这是有效代码:
int main()
{
for (auto ret = returnStrings(); auto e : ret.value())
std::cout << e << " ";
return 0;
}
更改为optional<reference_wrapper<vector>>
也不起作用,因为原始returnStrings
函数正在返回一个右值,这意味着如果不是用于复制省略,则原始对象将被移动分配,然后也被破坏。
因此,如果函数返回一个optional<vector>
非常重要,那么您的 for 循环将需要一些东西来正确初始化可选对象本身。
在使用它的模板基础类型时,您需要使用std::optional
包装器。 在您的情况下,它是std::string
,应该可以。
#include <iostream>
#include <vector>
#include <string>
#include <optional>
using namespace std;
using optional_vecs = std::optional<std::vector<std::string>>;
optional_vecs returnStrings()
{
std::vector<std::string> myVect{};
myVect.emplace_back("Name");
return std::optional{ myVect };
}
int main()
{
auto stringsOpt = returnStrings();
if (stringsOpt) {
for (auto& e : *stringsOpt)
std::cout << e << " ";
}
return 0;
}
此代码实际上适用于 GCC。
PS:令人惊讶的是,您的源代码无法在 MSVC 上编译。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.