答案已經被billz提供的,但我會嘗試生產一種解釋。
在C++獲取指向成員的指針時,表達式的結果不是指向表達式中存在的類型成員的指針,而是成員定義類型的指針成員。也就是說,表達式&B::Key
產生&A::Key
,因爲成員函數Key
在A
中定義,而不是在B
中定義。
一元&操作的結果是一個指向它的操作數:這是在§5.3.1/ 3,這是難以閱讀,但配備了一個例子限定。操作數應該是一個左值或一個合格的ID。如果操作數是一個qualified-id,它命名類型爲T的某個類C的非靜態成員m,則結果的類型爲「類型T的C類成員的指針」,並且是一個指定C :: m的前值。否則,如果表達式的類型是T,則結果的類型是「指向T的指針」,並且是一個prvalue,它是指定對象(1.7)的地址或指向指定函數的指針。 [注意:特別是,「cv T」類型的對象的地址是「cv T指針」,具有相同的cv限定。 - 注完] [實施例:
struct A { int i; };
struct B : A { };
... &B::i ... // has type int A::*
- 端示例]
這意味着你的模板實例相當於:
TT<B, &A::Key>
雖然指針到 - 成員到基的成員可以轉換爲指向成員的指向派生類型,對於非類型的非模板模特的特定情況不允許轉換的板參數。用於非類型的非模板的模板參數的轉換是在§14.3.2/ 5,這對於這種特殊情況下規定定義:
對於類型指針的非類型模板參數成員函數,如果模板參數的類型爲std :: nullptr_t,則應用空成員指針轉換(4.11);否則,不適用轉換。
由於&A::Key
不能收斂到int (B::*)() const
,所以模板實例化是格式不正確的。通過在模板實例化中添加強制轉換,您可以在實例化模板之前強制執行轉換,並且由於不需要轉換,實例化將變得有效。
你如何在TT中調用B :: key? – billz
我認爲這與問題無關。但我添加了一些代碼來顯示它。 – user1899020