2015-04-05 86 views
4

我讀an article指向虛擬成員函數的指針是否可比?

的成員函數指針可以被設置爲0,並且提供了操作符 ==和!=,但只爲同一類的成員函數指針。

我想了解C++ 11,§5.10。

§5.10/ 1它說的相同類型(指針轉換之後)

指針可以比較 是否相等。

§5.10/ 2它說

否則,如果任一是一個指向虛擬成員函數,所述 結果是不確定的。

現在考慮下面的測試程序。

#include <cassert> 

class ISomeClass 
{ 
public: 
    virtual ~ISomeClass() {} 

    virtual void a() = 0; 
    virtual void b() = 0; 
}; 

int main() 
{ 
    typedef void(ISomeClass::*MemberPtr)(); 

    MemberPtr mp = &ISomeClass::a; 

    assert(mp == &ISomeClass::a); 
    assert(mp != &ISomeClass::b); 

    return 0; 
} 

根據標準,斷言是否爲真或未指定?

+0

它們是「相同類型的指針」,所以/ 1適用,而不是/ 2(「否則」)。 – 2015-04-05 09:16:38

+2

指向成員的指針不是標準用語中的指針(請參閱[dcl.mptr]/3)。/2適用,但在這個特定的「否則」之前有很多/ 2。 「如果兩個操作數都爲空,則它們比較相等,否則如果只有一個爲空,則它們比較不相等,否則,如果其中一個是指向虛擬成員函數的指針,則結果未指定。它說,在之前描述了將操作數轉換爲相同類型的轉換。它看起來沒有指定給我。 – Wintermute 2015-04-05 09:22:52

+0

我的英語在這裏失敗了。 「或者」是指:指針中的任何一個,或者:不指向這兩個指針?意義是至關重要的,因爲標準中的後面是「否則它們比較相等,當且僅當它們會引用同一個派生對象的相同成員」,這意味着我的示例程序將遵循標準。 – DeMarcus 2015-04-08 22:28:58

回答

1

我認爲一般指針指向成員是移位對象地址。在指向虛擬方法的情況下,我認爲細節取決於實現。在一般情況下,我認爲這樣做不是一個好主意,但是如果指針在賦值期間解決了正確的覆蓋,它必須作爲標準指針指向成員函數,並且比較是移位比較和方法簽名比較。檢查reinterpret_cast以查看會發生什麼。

+0

感謝您的輸入!請注意,我們只比較同一純虛擬接口中的成員函數指針。即我們不會將來自接口的成員函數指針與子類中的重寫成員函數指針進行比較。 – DeMarcus 2015-04-05 11:51:43

+0

結果取決於編譯器。它可以檢查這個表達式是否錯誤,並拒絕編譯它。但是如果你能編譯它,比較必須導致預期的方式(斷言2失敗)。恕我直言。 – 2015-04-05 12:56:00

+0

是的,但不幸的是不便攜。甚至不在相同編譯器的不同版本之間。 – DeMarcus 2015-04-08 20:07:19