我试图获取一个指向函数模板实例的指针并将其转换为void*:
#include <stdio.h>
void plainFunction(int *param) {}
template <typename T>
void templateFunction(T *param) {}
int main() {
void *addr1=&plainFunction; //OK
void *addr2=&templateFunction<int>; //Compile error
}
Run Code Online (Sandbox Code Playgroud)
我收到以下错误(在Visual Studio 2008中)
main.cu(10) : error C2440: 'initializing' : cannot convert from 'void (__cdecl *)(T *)' to 'void *'
Context does not allow for disambiguation of overloaded function
Run Code Online (Sandbox Code Playgroud)
为什么会这样?功能templateFunction(对于具体类型T=int)不会过载.可以减去我所引用的函数的哪个实例.
如果我用以下内容替换erroneus行:
void (*foo)(int*)=&templateFunction<int>;
void *addr2=foo;
Run Code Online (Sandbox Code Playgroud)
它编译没有问题.
谢谢!
更新:
当正常指针void*被虚拟函数指针替换时void(*)(),正如James(谢谢)建议的那样,它会使错误消失:
void (*addr1)()=(void(*)())&plainFunction;
void (*addr2)()=(void(*)())(&templateFunction<int>);
Run Code Online (Sandbox Code Playgroud)
但是,如果错误是通过将函数指针转换为普通指针引起的,则编译器应该在两种情况下都会抱怨.但它没有,所以我继续假设它至少对于这个编译器来说是正确的.如果我没有记错的话,标准只是说,函数指针不具有像普通指针来表示,但它并没有禁止这一点.
Jam*_*lis 12
两者在技术上都是错误的:在C++中,你不能将函数指针转换为void*.
指向函数类型(如此void (*)(int*)处)是一种完全不同的类型,而不是指向对象类型(如此void*处).
允许完全转换的Visual C++(例如in void* addr1 = &plainFunction;)是一种语言扩展(使用/Za标志进行编译,禁用语言扩展,导致两行都被拒绝).
错误有点误导,当然,虽然其他一些编译器同样没有帮助(Comeau报告"错误:没有函数模板的实例"templateFunction"匹配所需的类型").
编译器应该在两种情况下都会产生错误.void由于函数不是对象(§1.8/ 1),因此函数指针不能根据标准§4.10/ 2 转换为*.Visual Studio 2008允许将此作为扩展,检查此错误.
使用typedef以避免误解:
typedef void(func)(int*); // declare func type
func* addr1 = &plainFunction; // OK
func* addr2 = &templateFunction<int>; // OK
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1494 次 |
| 最近记录: |