【问题标题】:How to pass std::optional struct that contains std::unique_ptr to a function?如何将包含 std::unique_ptr 的 std::optional 结构传递给函数?
【发布时间】:2021-09-25 20:24:21
【问题描述】:

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

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

这里是一个很容易重现问题的代码sn-p:

#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;

【问题讨论】:

  • 当它被传递给 func 时,您正在制作副本。通过 const 引用等来获取它。
  • 哇,您的问题的简化、清晰的minimal reproducible example,作为第一个问题,+1;这里太少见了。
  • 附带说明,至少在 Java 中,不鼓励使用 Optional 作为参数,因为已经有了可选参数的概念;不同的重载。

标签: c++ function c++17 unique-ptr stdoptional


【解决方案1】:

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

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

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

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

See live

【讨论】:

  • 谢谢@Jejo!这行得通。我认为 optional 相当于 unique_ptr ,所以我从来没有想过!
猜你喜欢
  • 2015-09-03
  • 1970-01-01
  • 2013-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-10
  • 2017-08-31
相关资源
最近更新 更多