如何将包含 std::unique_ptr 的 std::optical 结构传递给函数?

Roh*_*ran 3 c++ function unique-ptr c++17 stdoptional

我正在学习如何使用,但在将参数传递给函数时std::optional遇到问题,因为 Type 中包含 a ,这会阻止调用。std::optional<Type>std::unique_ptr

\n

将这样的变量 ( std::optional<Type>) 传递给函数的正确方法是什么?

\n

这是一个可以轻松重现该问题的代码片段:

\n
#include <iostream>\n#include <optional>\n#include <memory>\nusing namespace std;\n\nstruct myStruct\n{\n    std::unique_ptr<int> a;\n};\n\nint func(const myStruct& val, std::optional<myStruct> opt)\n{\n    if (opt.has_value())\n    {\n        return *(opt.value().a);\n    }\n    else \n    {\n        return *(val.a);\n    }\n}\n\nint main()\n{\n    cout << "Hello World";\n    myStruct val;\n    val.a = std::make_unique<int>(5);\n    std::optional<myStruct> opt = std::nullopt;\n    myStruct temp;\n    temp.a = std::make_unique<int>(10);\n    opt = std::move(temp);\n    std::cout << "result is " << func(val, opt) << std::endl;\n    return 0;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

我在上面的代码中看到的错误:

\n
main.cpp:35:47: error: use of deleted function \xe2\x80\x98std::optional::optional(const std::optional&)\xe2\x80\x99\n     std::cout << "result is " << func(val, opt) << std::endl;\n                                               ^\nIn file included from main.cpp:10:0:\n/usr/include/c++/7/optional:453:11: note: \xe2\x80\x98std::optional::optional(const std::optional&)\xe2\x80\x99 is implicitly deleted because the default definition would be ill-formed:\n     class optional\n           ^~~~~~~~\n/usr/include/c++/7/optional:453:11: error: use of deleted function \xe2\x80\x98constexpr std::_Enable_copy_move::_Enable_copy_move(const std::_Enable_copy_move&) [with _Tag = std::optional]\xe2\x80\x99\nIn file included from /usr/include/c++/7/optional:43:0,\n                 from main.cpp:10:\n/usr/include/c++/7/bits/enable_special_members.h:157:15: note: declared here\n     constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept  = delete;\n
Run Code Online (Sandbox Code Playgroud)\n

JeJ*_*eJo 5

由于member,您的myStruct只能间接移动(不可复制)std::unique_ptr<int> a;,默认情况下它也是不可复制的(仅允许移动)。

因此,可选变量opt(包含 struct myStruct)也只能间接移动。但是,在您的函数中,func您尝试opt按值传递,这实际上尝试复制底层结构,从而导致编译器错误。

您需要传递optconst ref,因为您无论如何都不会修改opt

int func(const myStruct& val, const std::optional<myStruct>& opt)
//                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
{
   // ..code
}
Run Code Online (Sandbox Code Playgroud)

观看直播