operator->重复,直到返回非类类型的值 [英] operator-> repeats until it returns a value of non-class type

查看:130
本文介绍了operator->重复,直到返回非类类型的值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据 13.3.1.2/8 ,或更好< a href =http://eel.is/c++draft/over.match.oper#footnote-129 =nofollow> footnote-129 (着重强调我):


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


我以为我知道 operator-> 基于返回类型),但我发现我完全不知道它是如何实际上工作(我的意思是,它的返回类型 )。



当我发现它,我想知道是否真的可以定义和使用像 double operator-> c $ c>为一个通用结构 S ,因为我从来没有使用过这样的运算符。

例如,考虑下面的代码:

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

int main(){
static_assert(3.14 == S {}。operator->(),!
}

语法相当难看,我看不到任何使用这样的运算符类似的。



让程序员返回 double float

解决方案

对于操作符重载的使用总是有问题的,并且应该大体上与用内在类型看到的操作符的行为一致。



解引用操作符 - > 和一元 * 应该像使用指针一样工作:



引用操作员重载


指针类型的操作符



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

  class my_ptr {
value_type& operator *();
const value_type& operator *()const;
value_type * operator->();
const value_type * operator->()const;
};

注意,这些也几乎总是需要一个const和一个非const版本。 对于 - >操作符value_type必须是类(或struct或union)类型,否则它们的实现会导致编译时错误。

1



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







显然,与 double 作为返回类型,但这与其他标准运算符(例如


$ b)可能的(非敏感, $ b

  #include< type_traits> 

struct S {
constexpr double operator->()noexcept {
return 3.14;
}
void operator =(const S& rhs){}
/ / ^^^^
};

Demo

  int main(){
static_assert(3.14 == S {}。operator->(),!);
}






>



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


仅仅意味着取消引用操作将立即停止。 em>作为返回类型。因此,返回一个内在类型将停止调用解引用操作。

如果返回一个指针,或者另一个重载 - > 的类型,






1
不是这样确保如果这个语句实际上是有效的,我和OPs的例子似乎证明是否。


According to 13.3.1.2/8, or better footnote-129 (emphasis mine):

[...] The process repeats until an operator-> function returns a value of non-class type.

I thought I knew how operator-> works (let me say, its recursive way based on the return type), but I see that I'm completely unaware about how it actually works (I mean, its return type).

When I found it, I wondered if one can really define and use something like a double operator->() for a generic struct S, for I've never used such an operator this way.
As an example, consider the code below:

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

int main() {
    static_assert(3.14 == S{}.operator->(), "!");
}

The syntax is quite ugly and I cannot see any use of such an operator or a similar one.

What is the real purpose of letting the programmers return a double or a float from this operator?
What could be a possible use for them?

解决方案

The use for operator overloads is always questionable, and should be mostly consistent with the behavior of operators as seen with the intrinsic types.

Thus the overloading of the dereferencing operators -> and unary * should behave like they are used with pointers:

Citing from Operator overloading:

Operators for Pointer-like Types

For defining your own iterators or smart pointers, you have to overload the unary prefix dereference operator * and the binary infix pointer member access operator ->:

class my_ptr {
        value_type& operator*();
  const value_type& operator*() const;
        value_type* operator->();
  const value_type* operator->() const;
};

Note that these, too, will almost always need both a const and a non-const version. For the -> operator value_type must be of class (or struct or union) type, otherwise their implementation results in a compile-time error.1

The unary address-of operator should never be overloaded.

For operator->*() see this question. It's rarely used and thus rarely ever > overloaded. In fact, even iterators do not overload it.


Obviously you can do that overload with double as return type, but that's no different from possible (non-sensical, less useful) overloads for other standard operators like e.g.

#include <type_traits>

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

Demo

int main() {
    static_assert(3.14 == S{}.operator->(), "!");
}


Your cite

[...] The process repeats until an operator-> function returns a value of non-class type.

merely means that the dereferencing operation will stop as soon a non-class type is received as return type. Thus returning an intrinsic type will stop calling the dereference operation.
If a pointer is returned, or another type that overloads -> that operator will be called automatically upon the returned type.


1 Not so sure if this statement is actually valid, my and OPs example seems to prove otherwise.

这篇关于operator-&gt;重复,直到返回非类类型的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆