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

How to pass std::optional struct that contains std::unique_ptr to a function?

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

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

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

#include <iostream>
#include <optional>
#include <memory>
using namespace std;

struct myStruct
{
    std::unique_ptr<int> a;
};

int func(const myStruct& val, std::optional<myStruct> opt)
{
    if (opt.has_value())
    {
        return *(opt.value().a);
    }
    else 
    {
        return *(val.a);
    }
}

int main()
{
    cout << "Hello World";
    myStruct val;
    val.a = std::make_unique<int>(5);
    std::optional<myStruct> opt = std::nullopt;
    myStruct temp;
    temp.a = std::make_unique<int>(10);
    opt = std::move(temp);
    std::cout << "result is " << func(val, opt) << std::endl;
    return 0;
}

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

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

你的 myStruct 只能间接移动(不可复制),因为成员 std::unique_ptr<int> a;,默认情况下也是不可复制的(只允许移动)。

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

您需要通过 const ref 传递 opt,因为无论如何您都没有修改 opt.

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

See live