operator->重复,直到返回非类类型的值

sky*_*ack 4 c++ operator-overloading return-type

根据13.3.1.2/8,或更好的脚注-129(强调我的):

[...]重复该过程,直到operator->函数返回非类类型的值.

我以为我知道它是如何operator->工作的(让我说,它基于返回类型的递归方式),但我发现我完全不知道它如何工作的(我的意思是它的返回类型).

当我找到它时,我想知道是否可以真正定义和使用类似于double operator->()通用结构的东西S,因为我从未以这种方式使用过这样的运算符.
例如,请考虑以下代码:

struct S { 
    constexpr double operator->() noexcept {
        return 3.14;
    }
};

int main() {
    static_assert(3.14 == S{}.operator->(), "!");
}
Run Code Online (Sandbox Code Playgroud)

语法非常难看,我看不到使用这样的运算符或类似运算符.

让程序员从这个运算符返回a double或a 的真正目的是什么float
什么可能是他们的用途?

πάν*_*ῥεῖ 5

运算符重载的使用总是有问题的,并且应该与运算符的行为一致,如内在类型所示.

因此,解除引用操作符->和一元的重载*应该像它们与指针一样使用:

引用运算符重载:

指针类型的运算符

要定义自己的迭代器或智能指针,必须重载一元前缀解引用运算符*和二进制中缀指针成员访问运算符 - >:

class my_ptr {
        value_type& operator*();
  const value_type& operator*() const;
        value_type* operator->();
  const value_type* operator->() const;
};
Run Code Online (Sandbox Code Playgroud)

请注意,这些也几乎总是需要const和非const版本.对于 - >运算符,value_type必须是类(或结构或联合)类型,否则它们的实现会导致编译时错误.1

一元地址运算符永远不应该重载.

对于运算符 - >*(),请参阅此问题.它很少使用,因此很少>超载.事实上,即使是迭代器也不会使它超载.


显然,您可以使用double返回类型执行重载,但这与其他标准运算符(如eg)的可能(非语义,不太有用)重载没有区别.

#include <type_traits>

struct S { 
    constexpr double operator->() noexcept {
        return 3.14;
    }
    void operator=(const S& rhs) {}
 // ^^^^
    void operator<(const S& rhs) {}
 // ^^^^
};
Run Code Online (Sandbox Code Playgroud)

Demo

int main() {
    static_assert(3.14 == S{}.operator->(), "!");
}
Run Code Online (Sandbox Code Playgroud)

你的引用

[...]重复该过程,直到operator->函数返回非类类型的值.

仅仅意味着一旦非类类型被接收为返回类型,则解除引用操作将停止.因此,返回固有类型将停止调用解除引用操作.
如果返回指针,或者重载->该运算符的其他类型将在返回的类型上自动调用.


1 不确定这个陈述是否真的有效,我和OP的例子似乎证明不是这样.