-1

关于是否以及如何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>将等同于简单键入.( <class>.<member>)

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

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

C global_C;

class D {
    C& operator.() { global_C.a = 'a'; return global_C; }
}

operator.也可以用作一元运算符,其作用很像 cast/getter。以下主要内容是有效的:

int main() {
    C foo;
    B bar;

    bar = foo.;
}

由此得出(<object>.).<member>等价于<object>..<member>

要在一元操作和二元/转发操作之间强制执行不同的行为,请使用传递给它的虚拟变量定义一元定义。

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

如果您希望禁止一元操作,您可以将其设置为delete

class F {
    C& operator.();//forwarded
    C& operator.(int) = delete;//F has no unary
}

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

class G {
    C g;
    const C& operator.() const;
    C& operator.();
}

这种实现是否operator.允许在所有情况下向operator.现有类添加一个而不破坏使用它的旧代码?有没有operator.模棱两可的情况?此外,还有一个更自以为是的问题,这种实现是否会导致任何高度不直观的结果?

4

1 回答 1

1

这里有很多问题。第一个是现在(some_expression)...可能是一个包扩展或一堆对.. 这似乎不值得。即使我们能修复它,那也太疯狂了。您永远不能...在任何模板中使用,并且由于将代码移动到模板中是会发生的事情,因此我们必须禁止在.任何地方重复使用以确保安全。


我们可以简化您的想法并从中获取页面operator->

a.b在当前标准中按原样进行评估。如果没有b找到并且aoperator.(), 则(a.operator.()).b改为评估。 注意:缺乏访问权限b不会导致operator.()使用。

想要“最小深度”的用户必须a.operator.()重复调用。想要一元的用户必须调用a.operator.()。调用时会发生零魔法a.operator.()——该方法只是被调用。(请注意,a.operator.()它不能用于operator.()查找自身,但这不是明确的规则,而是隐含在a.x工作方式中。)

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

于 2018-07-26T20:05:24.740 回答