C++ 与函数指针、cdecl和模板混淆

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; //

在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; // 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)=平方;//第三行,错了

cout
square
*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