2011-08-30 98 views
15

我看惯了语法像这样的函数指针的语法C++与函数参数类型的模板

int (*pointer_name) (float, char *); 
void call_function (void (*)(int), int); 

在我看到的类型使用这样一些C++ 03功能库:

abc::function<void(*)(int,float)> f; 

在C++ 11的std::function我看到这样

std::function<void(int,float)> f; 

存在丢失的012所给出的类型。为什么?

C++ 03 function<T>具有T与相应的函数指针是相同的类型。很容易想象实现。

std::function在C++ 11中得到了核心语言增强的支持。是否扩展了模板参数类型以适应可调用性?

回答

17

std::function(及其灵感,boost::function)不仅存储函数指针。它也可以存储函数对象。从这个意义上说,将一个函数签名作为模板参数传递的方式类似于智能指针如何将指针对象作为模板参数的类型,而不是指针类型!

对比度:

int* p; // indirection to an object of type int 
std::unique_ptr<int> q; // indirection to an object of type int 

typedef void signature_type(); // a function type 

// indirection to something callable with signature_type as a signature 
// i.e. f() has type void 
// only work for freestanding functions however 
signature_type* f; 

// indirection to something callable with signature_type as a signature 
// i.e. g() has type void 
// not restricted to function pointers! 
std::function<signature_type> g; 

这是一个很有用的约定。

+0

这比教科书指针语法好得多!我想知道为什么我们不这样正常地教... – spraff

+1

@spraff:可能是因为它是一个相对较新的创新,而且大多数教科书的周转率非常低。我仍然看到有人在学习Borland Turbo C++,这种语法似乎有很多麻烦。 – greyfade

3

函数类型在C++ 11中不新(请参阅C++ 98中的8.3.5)。 IIRC,对于TR1和提供的function提供的改进是相当小的。

8

没有什么神奇这里,类型

void(int,float) 

是函数没有名字的类型。它匹配一个功能,如void g(int x, float y)

使用模板你不要使用函数指针,你也可以使用函数类型。

8

与其他元素一样,函数有一个类型,您可以在不同的上下文中使用类型或指向该类型的指针。缺少的(*)您所期待的仅仅是指针语法。

int (*pointer_name) (float, char *); 
typedef int my_function_type(float,char*); 
my_function_type * pointer_name2; 

类型的pointer_namepointer_name2是相同的:指针返回int和需要的类型floatchar*两个参数的函数。请注意,这与int等其他类型完全相同,区别在于您不能声明变量为函数,只能使用指向函数的指针。

std::function(或boost::function)的接口只需要该函数的签名。类型参数不是指向函数的指针,而是函数的类型(如上面代码中的my_function_type