解释会员功能的访问装饰

发布于 2025-02-07 18:37:37 字数 1365 浏览 1 评论 0原文

在C ++ 11及以后,可以用&const&,OE &&&(或其他其他组合)。

如果一个人有几个过载,并且至少有一个过载,则其他人必须遵循同一约定。

pre c ++ 11样式:

struct A {
   void f() const {}  // #1
   void f()       {}  // #2
};

C ++ 11和更高版本:

struct  {
   void f() const& {}  // #3
   void f()      & {}  // #4
// void f()     && {}  // if necessary
};

直到今天,我虽然#4等效于#2,但今天我找到了一个反面示例:

struct A {
   void f()      & {}
// void f()     && {}  // commented for testing purposes, see below
}

struct B {
   void f()        {}
}
...
A{}.f();  // compile error: argument discards qualifiers
B{}.f();  // ok

https://godbolt.org/z/qtv6hms6e

那么,怎么办?以旧样式编写的未装置(非const)成员函数等同于其&&& 版本,取决于上下文(在调用点处)?

以下代码是正确的解释吗?

struct B {
   void f() {... some body...}
}

...和这个一样吗?

struct B {
   void f()  & {... some body...}
   void f() && {... some (same) body...}
}

...与此相同:

struct B {
   void f()  & {... some body...}
   void f() && {return f();}
}

In C++11 and later, one can decorate the member function with &, const&, oe && (or other combinations).

If one has several overloads, and at least one is specified like this, the others must follow the same convention.

Pre C++11 style:

struct A {
   void f() const {}  // #1
   void f()       {}  // #2
};

C++11 and later:

struct  {
   void f() const& {}  // #3
   void f()      & {}  // #4
// void f()     && {}  // if necessary
};

Until today, I though that #4 was equivalent to #2, but today I found a counter example:

struct A {
   void f()      & {}
// void f()     && {}  // commented for testing purposes, see below
}

struct B {
   void f()        {}
}
...
A{}.f();  // compile error: argument discards qualifiers
B{}.f();  // ok

https://godbolt.org/z/qTv6hMs6e

So, what is the deal? An undecorated (non-const) member function written in the old style is equivalent to both its && or & version depending on the context (at the calling point)?

Is the below code the correct interpretation?

struct B {
   void f() {... some body...}
}

...is the same as this?

struct B {
   void f()  & {... some body...}
   void f() && {... some (same) body...}
}

... which is the same as this:

struct B {
   void f()  & {... some body...}
   void f() && {return f();}
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

花辞树 2025-02-14 18:37:37

预选符的含义与假设隐式对象参数的限定符完全相同,该限定符传递的对象表达式的假设隐式对象参数。

因此,#4无法在prvalue上调用,因为非const lvalue参考无法绑定到prvalue,这解释了为什么a {}。}。f();>行不通。 (a {}是prvalue)

旧样式没有参考预选程序是奇怪的。它在过载分辨率中的表现就好像隐式对象参数是LVALUE参考(const或不取决于该限定符),但与正常函数参数相反,它可以作为目的而允许其绑定到RVALUES超负荷分辨率。

因此,要复制旧样式的不合格的行为,您需要指定& Qualified Overload和&&&&code> qualified Overload(至少如果函数为也不const合格)。 (在某些角度,两个合格的成员函数并不等于一个不合格的函数。我想一个简单的例子是尝试采用地址& b :: f。 )

The qualifiers have the exact same meaning as if they were the qualifiers on the hypothetical implicit object parameter which is passed the object expression of the member access expression.

So, #4 can not be called on a prvalue, because a non-const lvalue reference can not bind to a prvalue, explaining why A{}.f(); doesn't work. (A{} is a prvalue)

The old style without reference qualifier is the odd one. It behaves in overload resolution as if the implicit object parameter was an lvalue reference (const or not depending on that qualifier), but in contrast to normal function parameters it is allowed to bind to rvalues anyway for the purpose of overload resolution.

So to replicate the old style unqualified behavior, you need to specify both the &-qualified overload and the &&-qualified overload (at least if the function is not also const-qualified). (There are likely some corner cases where the two qualified member functions are not 100% equivalent to one unqualified one though. I guess a simple example would be trying to take the address &B::f.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文