我正在尝试创建一个标识函数的类模板,我可以在其中识别函数何时专门用于R (*) ()
的类模型,但在std::function
中您可以声明 return_type ()
},std::is_same< int(), int (*) () >.::value
为零。
此int ()
语句的含义是什么?int ()
和
之间有什么区别?
int (*) ()
更新:所以
int ()
是函数声明或函数类型,而int (*)()
是指向函数的指针。但是, int (std::string::)()
的类型函数是什么?它是什么东西比如 int std::string::
()
,或者像std::function
int(const std::string&)
一样?我怎么能让这个程序输出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 (SumType)(int,int)const;
class X{
public:
SumType sum;
};
int X::sum(int a,int b)const{
return a+b;
}
int main()
{
std::cout << IsSame< int (const std::string&,int,int)const,
decltype( &X::sum)>::value;
}
{{1 }}
答案 0 :(得分:8)
一个函数有一个类似void()
的类型,如果你获取它的地址,你会得到一个指向该函数void(*)()
的指针。它们的类型不同,尽管函数可以衰减为指向函数的指针,类似于数组衰减为指向第一个成员的指针。
这意味着您可以声明一个函数:
void f();
并将其指定给指向函数的指针(具有相同签名):
void (*p_to_f)() = f;
并且函数衰减到指向函数的指针
这就是为什么我认为很难理解void()
和void(*)()
之间的区别,但它们是不同的类型,这种差异在模板中很重要(这种衰变并不是必然的)发生)。
当衰变不发生时,一个重要的例子是匹配模板特化。考虑一下std::function
所做的事情:
template <class>
class function;
template <class R, class ... Args>
class function<R(Args...)> { /* ... stuff ... */ };
特殊化在函数类型上的事实与它专门用于指向函数类型的事实不同。
function<void(int,int)> f;//matches specialisation
function<void(*)(int,int)> g;//does not match specialisation
回应OP的评论(现已删除):
为了匹配指向函数的指针,您可以这样做:
template <class R, class ... Args>
function<R(*)(Args...)> : function<R(Args...>{};
这实际上意味着您将函数和指针视为相同的函数。如果要匹配尽可能多的函数,还必须考虑成员函数,const成员函数和noexcept
函数(从C ++ 17开始)。如果您想要完全彻底,还有&
,&&
,const &
,const&&
,volatile
等......但我除非他们真的出现,否则不会担心这些。