从返回 std::optional of std::vector 的函数中获取结果到调用方
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;
}
现在我遇到了崩溃和错误:
- 尝试添加字符串"name"时发生崩溃。
- 错误是当我尝试使用
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()
的使用寿命。
那么我怎么能以
functionName().Value()
的方式返回一个 std::optional 持有 std::vector .
你必须捕捉functionName()
的回报. 您可以执行所做的事情,或者在 C++20 中,您可以使用 ranged 的新init-语句版本,该版本是为此类情况构建的,看起来像
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 上编译。
- 如果我std::dynamic_pointer_cast并且底层dynamic_cast的结果为null,那么返回的sh
- ";结果类型必须是可从输入范围的值类型""构造的;创建std::vector时
- 从返回 std::optional of std::vector 的函数中获取结果到调用方
- 如何将 std::将结果绑定到 std::function
- 为什么这个涉及 std::enable_if 的模板元函数会产生不希望的结果?
- 使用类似的比较函数时,在 c++ 中为 std:sort 获得不同的结果
- 使用std::tie进行类似golang的错误处理,同时返回结果,是否有缺点?(C++11)
- std::chrono::duration::count函数的实际结果类型是什么
- std::atomic_flag初始化结果
- 为什么 std::get<T> 其中 T 是调用 constexpr 函数失败的结果?
- 为什么一个表达式中的 std::string 连接给出的结果与逐个字符不同的结果?
- 相同的结果 qsort vs std::sort
- 为什么 std::locale( " " ).name() 在 clang 和 gcc 上给出不同的结果?
- 使用 std ::transform 构造 std::vector.返回未命名结果的可能性?
- std::reduce 似乎将结果转换为整数
- libc++ 对 std::map/set::equal_range 的实现给出了意想不到的结果
- 如何避免 std::abs 的意外结果?
- 为什么 std::when_any 使用 std::tuple 而不是 std::vector 作为其结果类型?
- std::vector 在 Linux 和 Windows 中给出了不同的结果
- 如何修改 std::generate 的绑定成员函数的结果