以下代码:
#include <chrono>
#include <expected>
#include <stdexcept>
#include <string>
#include <thread>
#include <utility>
using namespace std::literals;
class Resource {
Resource() { }
public:
static std::expected<Resource, std::string> tryCreate() noexcept {
try {
return Resource();
} catch (const std::runtime_error& exc) {
return std::unexpected(exc.what());
}
}
static const Resource create() noexcept {
while (true) {
const auto resource{Resource::tryCreate()};
if (resource.has_value()) return resource.value();
else std::this_thread::sleep_for(1s);
}
}
Resource(const Resource&) = delete;
Resource(Resource&& other) noexcept {}
Resource& operator=(const Resource&) = delete;
Resource& operator=(Resource&& other) noexcept { return *this; }
~Resource() { }
void use() const noexcept {}
};
int main() noexcept {
const auto resource{Resource::create()};
resource.use();
}
…拒绝编译,出现错误:
<source>:25:42: error: call to deleted constructor of 'const Resource'
25 | if (resource.has_value()) return resource.value();
| ^~~~~~~~~~~~~~~~
<source>:29:3: note: 'Resource' has been explicitly marked deleted here
29 | Resource(const Resource&) = delete;
| ^
1 error generated.
Compiler returned: 1
我没有看到任何解释
cppreference
只允许移动的类型是不允许的,而且我在搜索互联网时无法立即找到其他有类似问题的人(尽管我对此还不熟悉,所以我的C++google fu可能不够)。我认为这可能与“复制省略”有关,但我真的很困惑。
是否不能使用仅限移动的类型
std::expected
?如果是,我如何修改我的示例代码使其正常工作(不定义复制构造函数)?
godbolt
-在Clang上使用-std=c++23失败,但我在GCC 14.2.1上遇到了类似的情况,同样是在-std=c++23上。