2012-04-08 63 views
1

...即使pointers to member functions are strange animals我可以安全地將一個指向const成員的指針轉換爲相同類型但非常量?

我正在編寫一個庫來將C++類綁定到Lua。我必須處理通過將某些類型對象推入Lua堆棧(因此將它們轉換爲void *)而引起的類型擦除。出於這個原因,爲了避免不同模板對於不同類型的數據(非常量和常量對象,非常量和常量成員,以及未來對易失性和非易失性進行雙重處理......)的過度擴散,我管理只需設置一個特定的標誌,即可在運行時綁定到Lua的對象的常量。

現在,我正在處理指向成員函數的指針。遵循我的設計到目前爲止,如果我可以安全地將一個指向const構件函數的指針轉換爲非const構造函數,然後對非const構造函數重複使用同一個模板,並在運行時用上述標記處理constness,我會很高興。

但還有另一個提示,讓我懷疑這是否真的可能。考慮下面的代碼:

#include <iostream> 
#include <typeinfo> 
using namespace std; 

struct A{ 
    const int a; 
    int b; 
}; 

template<typename T> struct tmpl; 

template<typename Class, typename FT> struct tmpl<FT(Class::*)>{ 
    static void f(){ 
     cout<<"non const"<<endl; 
    } 
}; 

//Try commenting this out, code compiles, both A::a and A::b instantiate the first template 
template<typename Class, typename FT> struct tmpl<const FT(Class::*)>{ 
    static void f(){ 
     cout<<"const"<<endl; 
    } 
}; 

int main(){ 
    cout<<typeid(&A::a).name()<<endl; //prints "M1AKi" 
    tmpl<decltype(&A::a)>::f();   //prints "const" 
    cout<<typeid(&A::b).name()<<endl; //prints "M1Ai" 
    tmpl<decltype(&A::b)>::f();   //prints "non const" 
    //Let's do what it seems that can be done implicitly (providing only one template specialization) in an explicit way 
    int(A::*memb)=(int(A::*))&A::a; 
    cout<<typeid(memb).name()<<endl; //prints "M1Ai" 
    tmpl<decltype(memb)>::f();   //prints "non const" 
} 

如此看來,無論these animals can even change their own size,在某些情況下,你可以安全地轉換(或至少,const_cast)他們到其他類型的(它們是否有意義)。

那麼,我的理由在其中一個步驟中是否可怕地錯誤,或者我可以這樣做,無論編譯器如何?我可以用指向const成員函數的指針來玩同樣的方法嗎?

回答

2

在「非常量」專業化中,簡單地推導出FT包含const限定符。它不會消失,它只是在通過

試試這個:如果你想殺死一個const

template<typename Class, typename FT> struct tmpl<FT(Class::*)>{ 
    static void f(){ 
     if (std::is_const<FT>::value) { 
      cout<<"const as non const"<<endl; 
     } else { 
      cout<<"non const"<<endl; 
     } 
    } 
}; 

http://ideone.com/g2Eie

,然後const_cast是作業的唯一可行的手段。

+1

恩,我還沒掌握這個模板機器。 – 2012-04-08 13:59:20

+0

你能幫我解決第二個問題:我可以用指向const成員函數的指針來玩同樣的方法嗎?現在的常量不包含在任何東西中(對吧?)。但是,無論如何,只要你在運行時自己管理常量,將'void(A :: f)()const'轉換爲'void(A :: f)()'是否安全? – 2012-04-08 22:06:48

+0

@LorenzoPistone成員函數不能被轉換,因爲'const'限定符適用於隱式'this'參數,並且沒有轉換可以改變函數參數的類型。希望這不是一個這樣的問題,你可以像處理常規參數列表中的參數一樣處理它。 – Potatoswatter 2012-04-09 01:47:11

相關問題