C++ 与函数指针、cdecl和模板混淆
在VisualStudio2019中,我编写了以下测试代码,但结果让我感到困惑C++ 与函数指针、cdecl和模板混淆,c++,visual-studio,templates,function-pointers,cdecl,C++,Visual Studio,Templates,Function Pointers,Cdecl,在VisualStudio2019中,我编写了以下测试代码,但结果让我感到困惑 #include <iostream> using namespace std; template<class T, class Func> int call(T x, Func f) { return f(x); } int square(int x) { return x * x; } int main() { int (*func0) (int) = square; //
#include <iostream>
using namespace std;
template<class T, class Func>
int call(T x, Func f) { return f(x); }
int square(int x) { return x * x; }
int main() {
int (*func0) (int) = square; // line 0, OK
//int (func1)(int) = square; // line 1, wrong
int (__cdecl *func1) (int) = square; // line 2, OK
//int (__cdecl func2)(int) = square; // line 3, wrong
cout << ((int(__cdecl*)(int)) square)(5) << endl; // line 4, OK
//cout << ((int(__cdecl)(int)) square)(5) << endl; // line 5, wrong
cout << call<int, int (*)(int)>(5, square) << endl; // line 6, OK
//cout << call<int, int ()(int)>(5, square) << endl; // line 7, wrong
cout << call<int, int(__cdecl*)(int)>(5, square) << endl; // line 8, OK
cout << call<int, int(__cdecl)(int)>(5, square) << endl; // line 9, OK
return 0;
}
似乎square
确实有类型int(\uu cdecl)(int)
。另外,我不明白为什么square
和*square
是同一类型的
有人能给我解释一下这些现象吗?线路错误:
int (func1)(int) = square; // line 1, wrong
如果缺少“*”,则需要:
int (*func1)(int) = square; // line 1, wrong
同
//int (__cdecl func2)(int) = square; // line 3, wrong
cout << ((int(__cdecl)(int)) square)(5) << endl; // line 5, wrong
//int(uu cdecl func2)(int)=平方;//第三行,错了
coutsquare
和*square
是相同的类型,因为函数会像数组一样衰减到指针,但在某些上下文下(就像数组一样)。特别是,衰减在typeid
和&
下被抑制,但在*
下不被抑制,因此typeid(square)
给出了square
的类型,int(uu cdecl)(int)
,而typeid(*square)
意味着typeid(*&square)
意味着typeid(square)
给出了同样的东西。这就导致了一个奇怪的事实,你可以写任意多的*
s,而它们都不会做任何事情:************square
与square
相同
现在,对于问题的其余部分,您编写的类型“函数获取int
返回int
”错误int()(int)
表示“函数不带参数返回函数带int
返回int
”。你想要int(int)
。那么这就行了:
cout << call<int, int(int)>(5, square) << "\n"; // line 7, fixed (FYI: endl is not normally necessary)
再次调整调用
的参数类型int(uu cdecl f)(int)
变成int(u cdecl*f)(int)
,这使得第9行的功能与第8行相同。是的,这是我理解的语法。我故意用这些错误的行来比较。我的主要问题是,为什么第9行可以?我明白了,这是一种我没有意识到的衰变。现在我明白了所有的逻辑。但这仍然是一件非常奇怪的事情,***************square==square
。。。谢谢你的回答。
cout << ((int(__cdecl*)(int)) square)(5) << endl; // line 5, wrong
cout << call<int, int(int)>(5, square) << "\n"; // line 7, fixed (FYI: endl is not normally necessary)
cout << call<int, int (__cdecl)(int)>(5, square) << "\n"; // line 9, OK