“std::optional::value”中引用限定的成员函数有什么意义

What's the point of ref-qualified member functions in `std::optional::value`

提问人:BIuesky 提问时间:7/21/2023 最后编辑:BIuesky 更新时间:7/21/2023 访问量:52

问:

根据 Cppreference,这些是签名:

constexpr T& value() &;
constexpr const T& value() const &;

constexpr T&& value() &&;
constexpr const T&& value() const &&;

使用 和 有什么意义? 特别是,我不明白超载的意义。 物体不应该被移动,那么我们为什么要这样做呢?&/const&&&/const&&const&&const

C++ std可选 ref-qualifier

评论

0赞 bolov 7/21/2023
因为它是一个泛型模板,所以它可以保存具有任何属性的任何类型。因此,出于优化目的,您需要一种方法将值移出临时值。你到底怀疑什么?
0赞 BIuesky 7/21/2023
我确切的怀疑是为什么我们需要 .const&&
0赞 bolov 7/21/2023
你无法知道 T 对象是做什么的。由于您位于通用上下文中,因此需要保留引用类型。例如,T 可能有一个方法重载。如果没有重载,用户将失去使用重载的能力。foo() const &&optional<T>value() const&&T::foo() const &&
0赞 BIuesky 7/21/2023
但是在这种情况下,如果一开始就不存在重载,或者我是否错过了您的重点,那么这将是首选函数?const&const&&
1赞 bolov 7/21/2023
我已经写了一个完整的答案。希望它能澄清我的意思。

答:

4赞 bolov 7/21/2023 #1

这一切都与通用模板上下文有关。这里的标准库需要支持所有可能的场景(你想象的和你无法想象的场景),因为我向你保证,某个地方的C++项目确实使用了它。

因此,如果您有一个用户定义的类型,如下所示:X

struct X
{
    void foo() &;          // 1
    void foo() const &;    // 2

    void foo() &&;         // 3
    void foo() const &&;   // 4
};

其中针对 const temporary () 与 const non-temporary () 进行了优化,标准库需要通过 来支持它。foofoo (4)foo (2)std::optional

如果缺少当用户有一个(它可以在通用模板上下文中)并尝试调用它时,将调用它而不是 .std::optinalconstexpr const T&& value() const &&;std::optional<X> const &&foofoo (2)foo (4)

我在这里打电话的意思:foo

const std::optional<X> && get_const_xvalue();
get_const_xvalue().get()foo();

// or in a generic template:

template <class Opt>
void bar(Opt&& o)
{
    std::forward<Opt>(o).get().foo();
}

// where `o` can be of type `std::optional<X> const &&`

有一个最坏的情况。想象一下这样的用户类型类型:Y

struct X
{
    void foo() &       = delete;  // 1
    void foo() const & = delete;  // 2

    void foo() &&;                // 3
    void foo() const &&;          // 4
};

在这种情况下,尝试临时访问 const 将导致编译器错误,而不是调用预期的重载。foofoo 4

评论

0赞 BIuesky 7/21/2023
我明白了,我认为我们可以简单地调用我们的 foo 的重载(所以在这种情况下,const T&& 的重载可能是),但在通用代码中这会很烦人。谢谢。真的很感激!std::move(get_const_temp().foo())const T&&std::optional::value=delete
1赞 bolov 7/21/2023
不客气。当然,const temporaries 不是很有用。但作为一个图书馆编写者,你永远不知道有人发明了什么疯狂的模式来使用它。