2017-10-05 45 views
3

下面的代碼編譯乾淨的GCC,但得到的鐺的錯誤:如何拋棄函數指針的constness?

typedef void (MyFuncPtr)(); 
void foo(const MyFuncPtr* ptr) 
{ 
    MyFuncPtr* myTestPtr = ptr; 
} 

鏘錯誤:

error: cannot initialize a variable of type 'MyFuncPtr *' (aka 'void (*)()') with an lvalue of type 'const MyFuncPtr *' 
    (aka 'void (const *)()') 

我曾嘗試以下解決方案,它們都得到除了C風格的錯誤投:

的const_cast:

MyFuncPtr* myTestPtr = const_cast<MyFuncPtr*>(ptr); 

錯誤:

error: const_cast to 'MyFuncPtr *' (aka 'void (*)()'), which is not a reference, pointer-to-object, or pointer-to-data-member 

reintepret_cast:

MyFuncPtr* myTestPtr = reinterpret_cast<MyFuncPtr*>(ptr); 

錯誤:

error: reinterpret_cast from 'const MyFuncPtr *' (aka 'void (const *)()') to 'MyFuncPtr *' (aka 'void (*)()') casts away 
    qualifiers 

C樣式轉換:

MyFuncPtr* myTestPtr = (MyFuncPtr*) ptr; 

成功!

問題:
爲什麼const_cast不能在函數指針上工作?
正在使用C風格唯一的解決方案嗎?
爲什麼這個工作在海灣合作委員會沒有鑄造?

在此先感謝!

編譯器版本:
* G ++版本4.6.3
*鐺版本3.5.0.210790

+0

'const MyFuncPtr *'類型幾乎是無稽之談,就像沒用(幾乎完全沒用)。而且我能想到的每個用途都沒有與它關聯的*實例*。爲什麼你的程序中有這種類型?過於通用的代碼? – Yakk

+3

請注意,'MyFuncPtr'實際上是一個函數類型,而不是函數指針類型(但這不會使您的問題無效,實際上它會使它更有趣) –

回答

3

在代碼中,MyFuncPtr是一個函數類型(不是一個函數指針類型)。您的代碼嘗試使用const MyFuncPtr類型,它將const應用於函數類型。

然而,根據在音符C++ 14 [dcl.fct]/6,不存在這樣的東西作爲一個常量限定函數類型:

The effect of a cv-qualifier-seq in a function declarator is not the same as adding cv-qualification on top of the function type. In the latter case, the cv-qualifiers are ignored. [Note: a function type that has a cv-qualifier-seq is not a cv-qualified type; there are no cv-qualified function types. —end note ]

這部分主要談論cv-qualifier-seq,這是在成員函數之後發生的限定詞。但是,順便說一下,它似乎指定一般應用於函數類型的cv-qualifiers將被忽略。

所以,你的代碼應該是一樣的:

typedef void (MyFuncPtr)(); 
void foo(MyFuncPtr* ptr) 
{ 
    MyFuncPtr* myTestPtr = ptr; 
} 

這意味着鐺被竊聽報告錯誤。

+0

我在這個實例中使用C++ 11,是否會影響您的回答? – Chadness3

+0

關於clang版本3.7,我開始得到以下符合上述答案的警告:3::3:10:警告:函數類型'MyFuncPtr'上的'const'限定符(又名'void()') -Wignored-qualifiers] void foo(const MyFuncPtr * ptr) – Chadness3

+0

@ Chadness3好的,聽起來像clang已經發現了3.5中的bug,並將它修復爲3.7 –