[英]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
我的問題是:為什么這段代碼有效? 這個模式有名字嗎?
- >運算符被調用兩次,但它只寫了一次。
因為這就是標准所說的:
1)
operator->
應該是一個不帶參數的非靜態成員函數。 它使用-> postfix-expression -> id-expression
實現類成員訪問如果T::operator->()
表達式x->m
被解釋為(x.operator->())->m
表示類型為T
的類對象x
T::operator->()
存在,如果操作符被重載決策機制選為最佳匹配函數(13.3)。
(強調我的)
在你的情況下, x
是foo
, m
是a()
,現在, Synchronized
重載operator->
, foo->a()
相當於:
(foo.operator->())->a();
foo.operator->()
是您在Synchronized
類中的重載,它返回一個LockedPtr
,然后LockedPtr
調用它自己的operator->
。
問問自己:它可能還有什么其他表現?
請記住,重載operator->
的重點是智能指針類可以使用與原始指針相同的語法。 也就是說,如果你有:
struct S
{
T m;
};
並且你有一個指針p
到S
,然后通過p->m
訪問S::m
,無論p
是S*
還是某個pointer_class<S>
類型。
使用->
和直接調用operator->
之間也有區別:
pointer_class<S> pointerObj;
S* p = pointerObj.operator->();
請注意,如果使用重載->
沒有自動降低額外級別,那么p->m
可能意味着什么? 如何使用過載?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.