繁体   English   中英

为什么编译器会两次调用 - >运算符

[英]Why does the compiler invoke the -> operator twice

以下代码摘自: https//github.com/facebook/folly/blob/master/folly/Synchronized.h

我最近看了一下Folly库,发现了一些有趣的东西。 请考虑以下示例:

#include <iostream>

struct Lock {
    void lock() {
        std::cout << "Locking" << std::endl;
    }
    void unlock() {
        std::cout << "Unlocking" << std::endl;
    }
};

template <class T, class Mutex = Lock >
struct Synchronized {
    struct LockedPtr {
        explicit LockedPtr(Synchronized* parent) : p(parent) {
            p->m.lock();
        }

        ~LockedPtr() {
            p->m.unlock();
        }

        T* operator->() {
            std::cout << "second" << std::endl;
            return &p->t;
        }

    private:
        Synchronized* p;
    };

    LockedPtr operator->() {
        std::cout << "first" << std::endl;
        return LockedPtr(this);
    }

private:
    T t;
    mutable Mutex m;
};

struct Foo {
    void a() {
        std::cout << "a" << std::endl;
    }
};

int main(int argc, const char *argv[])
{
    Synchronized<Foo> foo;
    foo->a();

    return 0;
}

输出是:

first
Locking
second
a
Unlocking

我的问题是:为什么这段代码有效? 这个模式有名字吗?

- >运算符被调用两次,但它只写了一次。

因为这就是标准所说的:

13.5.6类成员访问[over.ref]

1) operator->应该是一个不带参数的非静态成员函数。 它使用-> postfix-expression -> id-expression实现类成员访问如果T::operator->()表达式x->m被解释为(x.operator->())->m表示类型为T的类对象x T::operator->()存在,如果操作符被重载决策机制选为最佳匹配函数(13.3)。

(强调我的)

在你的情况下, xfooma() ,现在, Synchronized重载operator->foo->a()相当于:

(foo.operator->())->a();

foo.operator->()是您在Synchronized类中的重载,它返回一个LockedPtr ,然后LockedPtr调用它自己的operator->

问问自己:它可能还有什么其他表现?

请记住,重载operator->的重点是智能指针类可以使用与原始指针相同的语法。 也就是说,如果你有:

struct S
{
    T m;
};

并且你有一个指针pS ,然后通过p->m访问S::m ,无论pS*还是某个pointer_class<S>类型。

使用->和直接调用operator->之间也有区别:

pointer_class<S> pointerObj;
S* p = pointerObj.operator->();

请注意,如果使用重载->没有自动降低额外级别,那么p->m可能意味着什么? 如何使用过载?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM