【发布时间】:2013-09-23 21:03:06
【问题描述】:
我的类的接口包括一个可能不存在的对象的访问器。目前,它返回一个可能为空的指针。我想按照建议的here 用std::optional 替换指针。访问器有一个const 重载,它使用Meyers' const_cast trick 来避免重复相同的代码两次。
简而言之,我想替换这个:
T const * MyClass::get() const {
/* non-trivial */
}
T * MyClass::get() {
return const_cast<T *>(const_cast<MyClass const *>(this)->get());
}
用这个:
std::optional<T const &> MyClass::get() const {
/* non-trivial */
}
std::optional<T &> MyClass::get() {
auto t = const_cast<MyClass const *>(this)->get();
return t ? std::optional<T &>(const_cast<T &>(* t)) : std::nullopt;
}
替换似乎不令人满意,因为:
- 它引入了一个分支;
- 额外的复杂性在某种程度上违背了使重载成为轻量级的目标(并被编译器简单地优化掉)。
我假设引用的 std::optional 特化基本上可以归结为一个增加安全性的指针,因此想知道是否有某种方法可以保持指针解决方案的简单性。有没有更令人满意的方法来编写访问器重载以使用std::optional?
【问题讨论】:
-
您确定可以直接使用
std::optional的引用吗?阅读 n3690,我觉得它需要一个对象类型,例如指针或std::reference_wrapper。 -
现在还有支持
std::optional的编译器吗? -
你不能在引用上实例化 std::optional (提出提案的人认为这太有争议了,可能会阻止 optional 被添加到 C++1y 中)。从 n3690 (C++1y CD) 20.6.2p1 开始:“需要为引用类型或(可能是 cv 限定的)类型 in_place_t 或 nullopt_t 实例化模板可选的程序是格式错误的。”
-
optional位于树干末端 libc++ 中,可使用带有 -std=c++1y 的树干末端 clang 进行访问。它 static_asserts 用于引用类型。 -
optional刚刚从 C++14 中被选为 TS。它可能很快会移至 libc++ 中的<experimental/optional>。
标签: c++ pointers constants optional c++14