【问题标题】:Why is there no built-in way to get a pointer from an std::optional?为什么没有内置方法从 std::optional 获取指针?
【发布时间】:2022-09-22 23:25:12
【问题描述】:

使用std::optional 时经常会发生以下情况:

void bar(const Foo*);

void baz(const std::optional<Foo>& foo) {
    // This is clunky to do every time.
    bar(foo.has_value() ? &foo.value() : nullptr);
    
    // Why can\'t I do this instead?
    bar(foo.as_ptr());
}

这就是让采用std::optional 变得烦人的事情,因为那样将它与需要指针的现有代码一起使用是非常不方便的。那么为什么std::optional 不提供类似.as_ptr() 的东西呢?这似乎是一个非常明显的便利功能。

  • 猜测那是因为指针本身是“可选的”,因为它们可以为空,所以std::optional 对指针并没有那么大的意义。但如果这是你需要经常做的事情,那么也许你应该自己创建这样一个方便的功能?
  • &amp;foo.value() ? foo.has_value() : nullptr 不仅仅是“笨拙”,它是错误的。如果foo 不包含值,则value() 会引发异常。
  • 如果您有as_ptr(),则需要在使用此结果的地方检查nullptr 的结果。我看不到检查可选项是否具有某些价值的任何好处。
  • 没有什么能阻止你写T const* as_ptr(std::optional&lt;T&gt; const&amp;)
  • 更让我恼火的是bar 通过指针获取它的参数。你不能为此责怪std::optional:P

标签: c++ option-type stdoptional


【解决方案1】:

我没有官方答案,但对我来说根本不是通用的足以在所有情况下都有意义。 std::optional&lt;std::shared_ptr&lt;Foo&gt;&gt; 完美有效的(尽管我们可能会质疑为什么有人采用这种方法),std::optional&lt;Foo*&gt; 也是如此。

那么as_ptr() 在上述每种情况下会做什么呢? std::shared_ptr&lt;Foo&gt;*? Foo**?那些是正确的根据您的请求键入类型,但可能不会导致代码中的替换项仅下降。

如果您愿意,可以为您的用例编写一个简单的模板:

template <class T>
T* as_ptr(std::optional<T>& in)
{
    return in.has_value() ? &in.value() : nullptr;
}

int main()
{
    std::optional<int> f;

    std::cout << as_ptr<int>(f);
}

【讨论】:

    猜你喜欢
    • 2018-05-04
    • 2021-05-16
    • 2011-05-05
    • 2021-01-02
    • 2020-06-14
    • 1970-01-01
    • 1970-01-01
    • 2022-12-19
    • 2018-12-25
    相关资源
    最近更新 更多