std::optional<Class> a;
a.value_or( Class() ).GetMember();
为什么我们不能像这样做:
a.value_or().GetMember();
标准库能否在默认构造时专门定制 value_or
方法?
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
可以通过调用该类型的默认构造函数被转换(可以这么说)为任何类型。它还保留了原始解决方案的惰性属性。Default
而不是TypeName()
并没有那么长。 - Valeriy Savchenko
a.value_or({}).GetMember();
。 - Alexander Kondratskiyvalue_or
可能不是正确的选择。 - Eljay