【问题标题】:C++ typedef member function signature syntaxC++ typedef 成员函数签名语法
【发布时间】:2011-06-17 11:10:10
【问题描述】:

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

【问题讨论】:

  • 只是出于好奇,你为什么要这么做?
  • 我很困惑,最后一个typedef不是你想要的吗?
  • 这对我来说似乎不均匀。可以对在全局范围内声明的函数进行类型定义,但不能对方法进行类型定义。是的,我在区分签名和函数指针类型。
  • 是的 C++ 语法应该允许 int (foo::&memberf_reference)(int, int )

标签: c++ typedef member-functions method-signature


【解决方案1】:

关于笨拙的函数指针语法的问题,我个人使用备忘单:The Function Pointers Tutorialdownloadable here,感谢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 个。

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

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

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

【讨论】:

  • @BЈовић:这也是一个很好的链接......哦,谢天谢地我知道第二篇文章;)
  • The Function Pointers Tutorial下载 的新工作链接
  • 使用 C++11“使用”语法会怎样?
  • @paulm:好问题,已编辑。基本上是一样的,只是名字被提取出来了,所以更容易找到。
  • @Nikos:您可以在编译器中自己尝试语法:Return(Class::)(Args...) 不是有效的语法。 this(不是this*)始终是一个指针,尽管从不为空,并且作为指向方法的指针传递。调用语法为(this->*method)(args...)(ref.*method)(args...),又是一层诡异……
【解决方案2】:

您可以利用模板别名'typedefing'特性来分解现代C++(post 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; 

【讨论】:

    【解决方案3】:

    它对我有用:

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

    【讨论】:

    • 这是成员函数指针的 typedef。这项工作也适合我,但不是我所追求的;)
    • 好的,现在我知道你想要什么了。但是,如果您设法创建了这个 typedef,您打算如何使用它呢?
    【解决方案4】:

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

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

    但是 __closure 关键字是 bcb 语言的 'hack' 未标准化...

    【讨论】:

    • 成员函数指针和函数指针大小不同的事实对我来说似乎无关紧要。通常情况下,shortdouble 的大小不同,但您可以同时使用 typedef
    • this 指针通常作为第一个隐藏参数传递。我还没有听说过任何编译器使用 64 位指针将 this 指针转换为指向对象的指针。
    • 这绝对是错误的。 this 指针存储在 IA-32 目标机器上的(例如 MSC)ECX-Register 中。在这样的系统上,任何指针始终是 32 位的。
    【解决方案5】:

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

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

    【讨论】:

    • ::memberf_signature 怎么样?
    猜你喜欢
    • 2016-12-14
    • 2021-10-16
    • 1970-01-01
    • 2018-04-14
    • 2014-10-09
    • 1970-01-01
    • 2013-03-22
    • 1970-01-01
    相关资源
    最近更新 更多