我的`operator.`(操作符)规范向后兼容且明确吗?

时间:2018-07-26 19:36:25

标签: c++ operator-overloading language-lawyer operator-keyword c++20

据我所知,关于是否应该将placebo controlled以及如何引入的标准方面存在一些争论。我想到了这个想法的直观实现

这是我尝试指定使用NEAR

的尝试

NEAR的调用将首先尝试访问调用对象的成员(如默认行为)。如果失败 然后它将调用用户定义的operator.

为了强制最小深度,用户可以调用重复的operator.

示例:

operator.

显式调用operator..)等同于简单键入class A { int a; } class B { double a; A b; A& operator.() { return b; } } class C { char a; B c; B& operator.() { return c; } } int main() { C foo; foo.a // char foo..a // double foo...a // int foo....a // <error> foo.b // A foo..b // A (equivalent to previous) foo...b // <error> foo.c // B foo..c // <error> } operator.

<class>.operator.().<member>

operator。()的返回值不必是成员。例如,它可以返回对全局对象的引用。另外, 它可能比简单的return语句具有更多的代码;

.

<class>.<member>也可以用作一元运算符,非常像强制转换/获取程序。以下主要内容将有效:

foo.operator.().a is the equivelent to foo.a
foo.operator.().operator.().a is equivalent to foo..a

因此,C global_C; class D { C& operator.() { global_C.a = 'a'; return global_C; } } 等效于operator.

要强制一元运算和二进制/前向运算符之间的行为不同,请使用传递给它的虚拟变量定义一元定义。

int main() {
    C foo;
    B bar;

    bar = foo.;
}

如果您希望禁止一元运算,则可以将其设置为(<object>.).<member>

<object>..<member>

当然,允许使用通常的const和非const版本;

class E {
    C& operator.();//forwarded
    C& operator.(int dummy);//unary
}

delete的实现是否在所有情况下都允许某人将class F { C& operator.();//forwarded C& operator.(int) = delete;//F has no unary } 添加到现有类中 不会破坏使用它的旧代码? class G { C g; const C& operator.() const; C& operator.(); } 是否存在歧义?还有一点 有疑问的问题,这种实施是否会导致任何非直觉的结果?

1 个答案:

答案 0 :(得分:1)

这里有很多问题。首先是现在(some_expression)...可能是包扩展或对.的一堆调用。这似乎不值得。即使我们可以解决它,也将是精神错乱。您永远都不能在任何模板中使用...,并且由于发生了将代码移入模板的情况,因此为了安全起见,我们必须禁止在各处重复使用.


我们可以简化您的想法,并在operator->中浏览页面。

  

a.b在当前标准中按原样评估。如果未找到ba有一个operator.(),则将评估(a.operator.()).b注意:无法访问b不会导致使用operator.()

想要“最小深度”的用户可能必须反复致电a.operator.()。想要一元的用户必须致电a.operator.()。调用a.operator.()时会发生零魔术-只是调用了该方法。 (请注意,a.operator.()不能使用operator.()来查找自己,但这不是一个明确的规则,而是隐含在a.x的工作方式中。)

上面暗示了具有operator.的const重载的能力。没有一元版本(这样做会使访问二进制版本变得不可能,这似乎是不礼貌的)。只有奇怪的情况才比较冗长(一元.,“请点至少2次”等)。