2017-10-05 44 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 –