33

我想为成员函数签名声明类型定义。全局函数 typedef 如下所示:

typedef int (function_signature)(int, int);
typedef int (*function_pointer) (int, int);

但是我不能对成员函数做同样的事情:

typedef int (foo::memberf_signature)(int, int);   // memberf_pointer is not a member of foo
typedef int (foo::*memberf_pointer)(int, int);

这听起来合乎逻辑,因为foo::是访问类中成员的语法foo

我怎样才能 typedef 只是签名?

4

5 回答 5

27

关于笨拙的函数指针语法的问题,我个人使用了一份备忘单:函数指针教程可在此处下载,感谢Vector指出)。

但是,正如您所经历的,成员函数的签名与常规函数的签名有点不同。

您可能知道,成员函数有一个隐藏参数 ,this需要指定其类型。

// C++11 and above.
using Member = int (Foo::*)(int, int);

// C++03 and below.
typedef int (Foo::*Member)(int, int);

确实让您指定传递给函数的第一个元素将是 a Foo*(因此,当您想到它时,您的方法实际上需要 3 个参数,而不仅仅是 2.

但是还有另一个原因,强制您指定类型。

一个函数指针可能指向一个虚函数,在这种情况下事情会变得相当复杂。因此,内存中表示的大小会根据函数的类型而变化。实际上,在 Visual Studio 上,函数指针的大小可能是常规指针大小的 1 到 4 倍。这取决于函数是否是虚拟的,特别是。

因此,函数引用的类是签名的一部分,没有变通方法。

于 2011-01-29T08:36:47.107 回答
8

您可以通过利用模板别名的“类型定义”特性来分解现代 C++ 中的目标类(第 11 篇文章)。你需要的看起来像:

template<typename T>
using memberf_pointer = int (T::*)(int, int); 

然而在声明的时候,一个指向使用这种语法的成员函数的指针需要指定目标类:

// D is a member function taking (int, int) and returning int
memberf_pointer<foo> mp = &foo::D; 
于 2015-07-27T09:36:35.580 回答
1

它不适用于您当前的语法的原因是运算符优先级表明您指的是名为 的函数foo::memberf_signature,而不是任何类型的类型。

我不确定你是否可以这样做,但我想不出任何括号组合来诱导代码用 g++ 4.2 编译。

于 2011-01-28T19:57:13.880 回答
1

这个对我有用:

#include <iostream>

class foo
  {
public:
  int g (int x, int y) { return x + y ; }
  } ;

typedef int (foo::*memberf_pointer)(int, int);

int main()
  {
  foo f ;
  memberf_pointer mp = &foo::g ;
  std::cout << (f.*mp) (5, 8) << std::endl ;
  }
于 2011-01-28T21:24:40.017 回答
-3

好吧,基本上它不能工作(至少我不知道用g ++);使用 borland c++ 编译器会有 __closure 关键字。

它不编译的原因是,函数指针的大小(在 x86 机器上)总是占用 <<32bits>>;但是如果你想指向一个类(接口)签名,sizeof 必须是 64 位:this 指针是 32 位(因为类接口只在内存中一次),实际函数是 32 位

但是 __closure 关键字是 bcb 语言“hack”,没有标准化......

于 2011-01-28T20:08:17.613 回答