如何从 T 的移动/复制构造函数被删除并具有私有构造函数的函数返回 std::expect<T, E>

问题描述 投票:0回答:1
目前我有这段代码,运行良好:

#pragma once #include <expected> #include <wayland-server.h> class Display { private: struct wl_display *ptr; public: enum class Error { CannotCreateDisplay, }; Display() = delete; Display(struct wl_display *ptr) : ptr{ptr} { } Display(const Display &) = delete; Display(Display &&) = delete; Display &operator=(const Display &) = delete; Display &operator=(Display &&) = delete; ~Display() { wl_display_destroy_clients(this->ptr); wl_display_destroy(this->ptr); } static std::expected<Display, Error> create() { struct wl_display *ptr{wl_display_create()}; if (ptr == nullptr) { return std::unexpected{Error::CannotCreateDisplay}; } return {ptr}; } };
我想将 

Display(struct wl_display *)

 构造函数设为私有,但我不能,因为否则 
create
 会抱怨找不到任何可行的构造函数来调用 
Display

我发现的一个解决方案是为

Display

 创建一个移动构造函数,但是还有其他解决方案吗?

class Display { private: struct wl_display *ptr; Display(struct wl_display *ptr) : ptr{ptr} { } public: enum class Error { CannotCreateDisplay, }; Display() = delete; Display(const Display &) = delete; Display(Display &&) = delete; Display &operator=(const Display &) = delete; Display &operator=(Display &&) = delete; ~Display() { wl_display_destroy_clients(this->ptr); wl_display_destroy(this->ptr); } static std::expected<Display, Error> create() { struct wl_display *ptr{wl_display_create()}; if (ptr == nullptr) { return std::unexpected{Error::CannotCreateDisplay}; } return {ptr}; // ERROR: can't find any viable constructor } };
    
c++ constructor private public
1个回答
0
投票
当然可以,这基本上是利用

std::expected

 的一元运算符。同样的方法也适用于
std::optional

而不是

return {ptr};
您可以绕道另一个

std::expected

,并就地转换值:

return std::expected<wl_display*, Error>{ptr}.transform( [](wl_display* ptr) -> Display { return {ptr}; } );
演示:

https://godbolt.org/z/W5o8rzxK9

© www.soinside.com 2019 - 2024. All rights reserved.