鉴于声明 void close_file_func(std::FILE* fd){}
我发现 decltype(&close_file_func)
是一种 void (*)(_IO_FILE*)
而 decltype(close_file_func)
是一种 void (_IO_FILE*)
?
您可以通过以下方式查看相关代码 https:/godbolt.orgzQK5q3o.
为了方便大家,我把代码和执行输出贴在下面。
#include<iostream>
#include<typeinfo>
void close_file_func(std::FILE* fd);
int main()
{
std::cout << typeid(close_file_func).name() << std::endl;
std::cout << typeid(&close_file_func).name() << std::endl;
}
//Terminate outputs:
//FvP8_IO_FILEE
//PFvP8_IO_FILEE
还有 echo 'PFvP8_IO_FILEE' | c++filt -t
说 void (*)(_IO_FILE*)
,
echo "FvP8_IO_FILEE" | c++filt -t
说 void (_IO_FILE*)
.
而这个表达式(std::cout << (close_file_func == &close_file_func) << std::endl;
)是合法的。你看。close_file_func == &close_file_func
返回 true
.
我想了又想,但我还是不明白。如果有任何关于这个问题的提示,我将感激不尽。
你可能会认为,这两个函数指针的类型应该是一样的。是的。函数到指针的隐式转换 在某些情况下可能会被执行1但不是为了 decltype(close_file_func)
(和 typeid(close_file_func)
).
当与实体一起使用时。decltype
将产生实体的类型;所以 decltype(close_file_func)
准确地产生函数类型,即。void (_IO_FILE*)
.
1)如果参数是一个未括号的id表达式或一个未括号的类成员访问表达式,那么decltype就会产生这个表达式命名的实体的类型。
另一方面,如果参数是无括号的id表达式或无括号的类成员访问表达式,那么decltype将产生这个表达式命名的实体的类型。&close_file_func
取函数的地址并返回函数指针,则 decltype(&close_file_func)
得出函数指针类型,也就是 void (*)(_IO_FILE*)
.
1 对于 operator==
,
(重点是我)
在所有情况下,对于内置的运算符,lhs和rhs必须具有以下两种情况之一
- 算术型或枚举型(见下文算术比较运算符)
- 指针类型(参见下面的指针比较运算符)
在应用lvalue-to-rvalue、array-to-pointer和rvalue-to-pointer之后。 函数到指针的标准转换.
函数到指针的隐式转换是在左操作数上进行的,所以...。close_file_func == &close_file_func
是比较函数指针。