为什么 std::optional::value_or 没有默认 ctor 类型的专用化?

Why std::optional::value_or dont have a specialization for default ctor types?

本文关键字:类型 ctor 默认 专用 optional std value 为什么 or      更新时间:2023-10-16
std::optional<Class> a;
a.value_or( Class() ).GetMember();

为什么我们不能这样做:

a.value_or().GetMember();

标准是否可以在默认可构造的基础上专门化value_or

不幸的是,这个value_or没有这个选项,我同意Max Langhof的评论,它应该是一个单独的函数value_or_default

然而,正如 Eljay 在此评论中指出的那样,问题中的代码可能会给具有昂贵默认构造的类带来问题。在optional不携带值的情况下,我们不希望调用默认构造函数。

我已经为这种特定情况整理了一些解决方法:

struct default_constructor_t {
explicit default_constructor_t() = default;
};
inline constexpr default_constructor_t default_constructor{};
class Class {
...
Class(default_constructor_t) : Class{} {}
...
};
int GetMember(std::optional<Class> Object) {
return Object.value_or(default_constructor).GetMember();
}

在此解决方案中,您需要向类添加额外的隐式构造函数。这个解决方案也很懒惰。仅当默认构造函数没有值时,它才会调用optional构造函数。

上发:经过一番思考,我相信我想出了一个更通用的解决方案,即使开发人员无法修改的类型也可以使用。即使一个人有这种能力,代码越少越好,对吧?

struct DefaultConstructed {
template <class T> operator T() const {
return T();
}
};
constexpr DefaultConstructed Default;
class Class {
...
};
int GetMember(std::optional<Class> Object) {
return Object.value_or(Default).GetMember();
}

此解决方案使用转换运算符而不是隐式构造。名为Default的特殊对象可以通过调用此类型的默认构造函数(可以说(转换为任何类型的。它还保留了原始解决方案的良好属性,即懒惰。