C++ typedef 成员函数签名语法

发布于 2024-10-15 08:22:16 字数 440 浏览 4 评论 0原文

我想声明成员函数签名的类型定义。全局函数 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。

我怎样才能只输入签名?

I want to declare type definition for a member function signature. Global function typedefs look like this:

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

But I'm not able to the same thing for a member function:

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

It sounds logically to me, because foo:: is the syntax to access a member in the class foo.

How can I typedef just the signature?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

心如狂蝶 2024-10-22 08:22:16

对于有关尴尬的函数指针语法的问题,我个人使用备忘单: 函数指针教程 (,感谢 Vector 指出)。

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

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

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

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

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

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

函数指针可能引用虚拟函数,在这种情况下,事情会变得非常复杂,因此,内存中表示的大小会发生变化。事实上,在 Visual Studio 上,函数指针的大小可能在常规指针大小的 1 到 4 倍之间变化,这取决于函数是否是虚拟的,

因此,函数所引用 的类。是签名的一部分,并且没有解决方法。

For questions regarding the awkward function pointer syntax, I personally use a cheat-sheet: The Function Pointers Tutorial (downloadable here, thanks to Vector for pointing it out).

The signature of a member function, however, is a bit different from the signature of a regular function, as you experienced.

As you probably know, a member function has a hidden parameter, this, whose type need be specified.

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

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

does let you specify that the first element passed to the function will be a Foo* (and thus your method really takes 3 arguments, when you think of it, not just 2.

However there is another reason too, for forcing you to specify the type.

A function pointer might refer to a virtual function, in which case things can get quite complicated. Therefore, the very size of the in-memory representation changes depending on the type of function. Indeed, on Visual Studio, a function pointer's size might vary between 1 and 4 times the size of a regular pointer. This depends on whether the function is virtual, notably.

Therefore, the class the function refers to is part of the signature, and there is no work-around.

肥爪爪 2024-10-22 08:22:16

您可以利用模板别名“类型定义”特性在现代 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; 

You can factor out the target class in modern C++ (post 11) by utilizing the 'typedefing' qualities of template aliases. What you need would look like like:

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

Yet at the point of declaration, a pointer to member function utilizing this syntax would need to specify the target class:

// D is a member function taking (int, int) and returning int
memberf_pointer<foo> mp = &foo::D; 
情徒 2024-10-22 08:22:16

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

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

The reason it doesn't work with your current syntax is that operator precedence dictates that you're referring to a function named foo::memberf_signature, not any sort of type.

I don't know for sure if you can do this or not, but I couldn't come up with any combination of parenthese that induced the code to compile with g++ 4.2.

独自唱情﹋歌 2024-10-22 08:22:16

它对我有用:

#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 ;
  }

It works for me:

#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 ;
  }
揽月 2024-10-22 08:22:16

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

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

但 __closure 关键字bcb 语言“hack”未标准化...

Well basically it can't work (at least I know no way using g++);
Using borland c++ compiler there would be the __closure keyword.

The reason why it does not compile is, that sizeof the functionpointer (on a x86 machine) occupies always <<32bits>>; but if you want to point to a class (interface) signature, the sizeof has to be 64bit: 32 bit for the this pointer (as the class interface is in the memory only once) and 32 bit for the actual function

But the __closure keyword is a bcb language 'hack' not standardized...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文