error: no matching function for call to 'std::optional<smoltcp::Buffer>::optional(smoltcp::Buffer&)'

error: no matching function for call to 'std::optional<smoltcp::Buffer>::optional(smoltcp::Buffer&)'

我正在尝试创建一个 returns 一个 std::optionalBuffer 的函数:

std::optional<Buffer> receive(SmolSocket smolSocket)
{
   //...
   return std::optional<Buffer>(buffer);
}

其中 Buffer 就是

struct Buffer
{
public:
   std::unique_ptr<uint8_t[]> data;
   size_t len = 0;
   bool empty = false;

   Buffer(CBuffer cBuffer)
   {
      data = std::unique_ptr<uint8_t[]>(cBuffer.data);
      len = cBuffer.len;
   }

   Buffer(bool empty)
   {
      data = std::unique_ptr<uint8_t[]>(nullptr);
      this->len = 0;
      this->empty = empty;
   }

   uint8_t* getData()
   {
      return data.get();
   }
};

但是我遇到了很多错误:

/workspaces/libopenvpnclient/src/libopenvpn/../../smoltcp_cpp_interface/src/virtual_tun/interface.h:283:52: error: no matching function for call to 'std::optional<smoltcp::Buffer>::optional(smoltcp::Buffer&)'
  283 |                 return std::optional<Buffer>(buffer);

/usr/include/c++/9/optional:760:2: note: candidate: 'template<class ... _Args, typename std::enable_if<__and_v<std::is_constructible<smoltcp::Buffer, _Args&& ...> >, bool>::type <anonymous> > constexpr std::optional<_Tp>::optional(std::in_place_t, _Args&& ...)'
  760 |  optional(in_place_t, _Args&&... __args)
      |  ^~~~~~~~
/usr/include/c++/9/optional:760:2: note:   template argument deduction/substitution failed:
/usr/include/c++/9/optional:758:56: error: no type named 'type' in 'struct std::enable_if<false, bool>'
  758 |         _Requires<is_constructible<_Tp, _Args&&...>> = false>

note:   'smoltcp::Buffer' is not derived from 'std::optional<_Tp>'
  283 |                 return std::optional<Buffer>(buffer);

我在其他情况下使用过std::optional,我看不出这里有什么问题。

我也试过使用return std::optional<Buffer>{buffer};

简而言之: 您应该将复制或移动构造函数添加到 Buffer

更多详情:

您有 Buffer 对象并需要创建另一个 Buffer(在 std::optional 中),但是 Buffer 中没有可以接受参数的构造函数通过。编译器 不会生成 默认 copy/move-constructors,因为您声明了自定义的。因此,您应该从 boolCBuffer 构造 std::optional<Buffer> 或添加另一个 const Buffer&Buffer&&.

问题是,为了做到

std::optional<Buffer>(buffer);

您需要一个复制或移动构造函数。当您提供参数化构造函数(即 Buffer(CBuffer cBuffer))时,编译器不会同时生成它们。所以你需要明确提供它们。

但是,对于您的情况,您还有一个问题。 成员data不可复制(即std::unique_ptr<uint8_t[]>),意思是您只能提供移动构造函数。

因此提供移动构造函数

struct Buffer
{
public:
   Buffer(Buffer&& rhs)
      : data{ std::move(rhs.data) }
      , len{rhs.len}
   {}
   // ... other code
};

并移动函数中的buffer

std::optional<Buffer> receive()
{
   // ...
   return std::optional<Buffer>(std::move(buffer));
}

(See a minimal example demo)