2013-01-12 177 views
2

我的代碼如下無法將重載的函數指針轉換爲成員函數指針?

class A 
{ 
public: 
    int Key() const; 
}; 

class B : public A 
{}; 

template<class T, int (T::*MemFunction)() const> 
class TT 
{ 
public: 
    int Get() const    {return (m_t.*MemFunction)();} 

private: 
    T m_t; 
}; 

TT<B, &B::Key> t; // Wrong, cannot convert overloaded function 
        // to int (T::*MemFunction)() (VS2010) 

爲什麼,以及如何以類似的方式工作?由於

+0

你如何在TT中調用B :: key? – billz

+0

我認爲這與問題無關。但我添加了一些代碼來顯示它。 – user1899020

回答

1

的鑄造制應該使其工作:

typedef int (B::*Key)() const; 
TT<Key(&B::Key)> t; 
t.Get(); 
+0

它的工作原理。謝謝!!! – user1899020

2

答案已經被billz提供的,但我會嘗試生產一種解釋。

在C++獲取指向成員的指針時,表達式的結果不是指向表達式中存在的類型成員的指針,而是成員定義類型的指針成員。也就是說,表達式&B::Key產生&A::Key,因爲成員函數KeyA中定義,而不是在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,所以模板實例化是格式不正確的。通過在模板實例化中添加強制轉換,您可以在實例化模板之前強制執行轉換,並且由於不需要轉換,實例化將變得有效。