int()与int(*)()的区别及成员函数类型匹配问题求解
一、int() 和 int(*)() 的核心区别
先把两个类型的本质说透:
int()是函数类型,代表「返回int、无参数的函数」这个抽象类型本身——就像int是整数类型一样,它描述的是函数的“蓝图”,不能直接用来声明变量,但可以作为模板参数、typedef的目标等。int(*)()是函数指针类型,指向符合「返回int、无参数」特征的函数的指针,这是一个可实例化的类型,比如你可以写int(*)() func_ptr = &my_func;来定义一个函数指针变量。
这就是std::is_same<int(), int(*)()>::value返回0的原因——它们是完全不同的类型,一个是函数本身的类型,一个是指向函数的指针类型。而std::function<int()>能正常工作,是因为std::function的模板参数设计为接受函数类型,内部会自动处理成可调用的包装,本质是对函数指针、仿函数等可调用体的封装。
二、成员函数类型:int(std::string::)() 到底是什么?
你提到的int(std::string::)() 是非静态成员函数类型,完整的标准写法是int (std::string::)()(注意括号的位置不能少),它代表std::string类中「返回int、无参数」的非静态成员函数的类型。
要区分几个容易混淆的概念:
int std::string::():这是错误的写法,C++中成员函数类型必须用(类名::)的形式来限定所属类,所以正确的成员函数类型必须带括号包裹类名::。std::function<int(const std::string&)>:这是可调用对象的包装类型,它可以接受「接受const std::string&参数、返回int」的任意可调用体(比如普通函数、lambda、绑定了对象的成员函数),但它和int (std::string::)()完全不是一回事——后者是未绑定对象的成员函数类型,调用它必须附带一个类对象(或指针)作为隐含的第一个参数。
另外,带const限定的成员函数类型(比如你代码里的SumType),完整类型是int (X::)(int, int) const,代表X类中「返回int、接受两个int参数、且是const成员函数」的类型。
三、修改代码让IsSame输出1的方法
你的代码里IsSame的两个模板参数类型完全不匹配:
- 第一个参数
int (const std::string&,int,int)const是一个「接受const std::string&、两个int参数,返回int的const成员函数类型」,但X::sum是X类的成员函数,它的实际类型是int (X::)(int, int) const,两者没有任何关联。
要让输出为1,必须让两个模板参数的类型完全一致。修改后的代码如下:
#include <iostream> template<typename A,typename B> struct IsSame{ enum{ value = 0}; }; template<typename A> struct IsSame<A,A>{ enum{ value = 1 }; }; typedef int (X::SumType)(int,int)const; // 修正为X类的成员函数类型 class X{ public: SumType sum; }; int X::sum(int a,int b)const{ return a+b; } int main() { // 两个参数类型完全匹配:都是X类的const成员函数类型 std::cout << IsSame< int (X::)(int,int)const, decltype( &X::sum)>::value; // 也可以用typedef的SumType简化写法: // std::cout << IsSame<SumType, decltype(&X::sum)>::value; }
这段代码运行后会输出1,因为int (X::)(int,int)const和decltype(&X::sum)的类型完全相同。
额外补充:如果你想测试成员函数类型和成员函数指针类型的区别,可以试试IsSame<int (X::)(int,int)const, int (X::*)(int,int)const>::value,结果会是0——和普通函数类型与函数指针类型的区别逻辑一致。
内容的提问来源于stack exchange,提问作者Diego Teixeira de Souza

