【问题标题】:How to construct a std::optional of a struct with std::shared_ptr如何使用 std::shared_ptr 构造结构的 std::optional
【发布时间】:2021-11-29 21:20:24
【问题描述】:

我正在尝试使用具有 shared_ptr 的类创建一个可选项,但隐式删除的构造函数阻止我使用 make_optional 来创建它。

是手动编写该构造​​函数的唯一选择吗?

这是一个简单的复制:

https://onlinegdb.com/DcWzF1NAt

#include <optional>
#include <memory>
class A
{
public:
 A(int v):
  val{v}
  {}
 int val;   
};

class B
{
public:
 B(std::shared_ptr<A>& a):
   a{a}
 {}
 
 const std::shared_ptr<A> a;   
};


int main()
{
  std::shared_ptr<A> a = std::make_shared<A>(3);
  
  std::optional<B> b;
  b = std::make_optional<B>(a);
}

导致编译错误

main.cpp:31:30: error: use of deleted function ‘std::optional& std::optional::operator=(std::optional&&)’
   b = std::make_optional<B>(a);
                              ^
In file included from main.cpp:4:0:
/usr/include/c++/7/optional:453:11: note: ‘std::optional& std::optional::operator=(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 ‘std::_Enable_copy_move& std::_Enable_copy_move::operator=(std::_Enable_copy_move&&) [with _Tag = std::optional]’
In file included from /usr/include/c++/7/optional:43:0,
                 from main.cpp:4:
/usr/include/c++/7/bits/enable_special_members.h:246:5: note: declared here
     operator=(_Enable_copy_move&&) noexcept                         = delete;
     ^~~~~~~~

【问题讨论】:

  • 为什么不使用std::optional&lt;B&gt; b(a);?编译
  • 我不想在这个例子中添加class C,但是在我原来的问题中我不能这样做,因为make_optional是在class C中的一个方法中调用的,并且optional&lt;B&gt;class C 的成员

标签: c++ c++17 stdoptional


【解决方案1】:

导致问题的不是隐式删除的构造函数,而是隐式删除的复制赋值运算符,与std::shared_ptr无关,这是因为您已将B::a成员声明为const。这里的解决方案是不要将其标记为const

class B
{
public:
 B(std::shared_ptr<A>& a):
   a{a}
 {}

 std::shared_ptr<A> a;   
};

编译器删除复制赋值运算符的原因是它必须能够修改该成员;我们可以通过一个稍微简单的例子来了解这一点:

class NoCopyAssign {
 public:
  NoCopyAssign(int a) : mA(a) {}
 private:
  const int mA;
 };

通常,复制赋值运算符大致相当于:

NoCopyAssign &operator=(const NoCopyAssign &other) {
  mA = other.mA;
  return *this;
}

但是这是不可能的,因为mAconst int,所以你不能改变它的值。 };

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-20
    • 1970-01-01
    • 2023-03-15
    • 2019-10-11
    • 1970-01-01
    • 2021-09-25
    • 2012-08-13
    相关资源
    最近更新 更多