简体   繁体   English

C ++:指向虚拟成员函数的单态版本的指针?

[英]C++: Pointer to monomorphic version of virtual member function?

In C++, it's possible to get a pointer to a (non-static) member function of a class, and then later invoke it on an object. 在C ++中,可以获得指向类的(非静态)成员函数的指针,然后在对象上调用它。 If the function was virtual, the call is dispatched dynamically depending on the dynamic type of the object. 如果函数是虚函数,则根据对象的动态类型动态调度调用。 It's also possible (not using a member pointer) to call virtual member functions of objects monomorphically, by explicitly providing the scope containing the version to use. 通过显式提供包含要使用的版本的范围,也可以(不使用成员指针)以单态方式调用对象的虚拟成员函数。 The following code demonstrates this: 以下代码演示了这一点:

#include <iostream>
using std::cout; using std::endl;

struct Foo
{
    virtual void foo() { cout << 1 << endl; }
};

struct Foo2: public Foo
{
    virtual void foo() { cout << 2 << endl; }
};

int main( int, char** )
{
    Foo *foo = new Foo2;

    void (Foo::*foo_pointer)() = &Foo::foo;

    foo->foo();            // prints 2
    foo->Foo::foo();       // prints 1
    (foo->*foo_pointer)(); // prints 2
}

What I would like to do is combine the two, and get a pointer to the monomorphic version of a member function; 我想要做的是将两者结合起来,并获得指向成员函数的单态版本的指针; ie, I want a pointer to Foo::foo which always calls the base class version of foo, and prints 1, even if it is invoked on a Foo2. 即,我想要一个指向Foo :: foo的指针,它总是调用foo的基类版本,并打印1,即使它是在Foo2上调用的。 However, I haven't been able to find a way to do this. 但是,我还没有找到办法做到这一点。 Is it possible? 可能吗?

(Other than the tedious manual way of writing a new non-virtual function which makes the monomorphic call, and then getting a pointer to that.) (除了编写一个新的非虚函数的繁琐的手动方式,它进行单态调用,然后获得指向它的指针。)

It's possible in GCC , but the way it's documented in C++ language extensions section suggests there's no portable way to do it. 它可能在GCC中 ,但它在C ++语言扩展部分中记录的方式表明没有可移植的方法来实现它。

You can do two things: 你可以做两件事:

  1. If you control the class, create a non-virtual function and a virtual wrapper for it and when you know you don't need virtual dispatch, just take address of the non-virtual one. 如果您控制该类,请为其创建非虚函数和虚拟包装,当您知道不需要虚拟调度时,只需获取非虚拟调度的地址。
  2. If you don't, create a template functor that will hold the member pointer and do the explicit scope call. 如果不这样做,请创建一个模板函子,该函数将保存成员指针并执行显式范围调用。

To elaborate with a code example for a wrapper function (and despite the fact the OP wanted to avoid this method!) as in many cases this is the pragmatically preferable solution: 详细说明包装器函数的代码示例(尽管事实上OP想要避免使用此方法!),因为在许多情况下,这是一个实用的解决方案:

#include <iostream>
using std::cout; using std::endl;

struct Foo
{
    virtual void foo() { cout << 1 << endl; }
};

struct Foo2: public Foo
{
    virtual void foo() { cout << 2 << endl; }
};

void monomorphicFooFoo( Foo * f ) { f->Foo::foo(); }

int main()
{
    Foo *foo = new Foo2;

    void (*baseFoo)( Foo * ) = &monomorphicFooFoo;
    baseFoo( foo ); // Prints 1
}

In other words : you want to cheat. 换句话说:你想作弊。

No, it is not possible because that is how the polymorphism in combination with pointer to member method works. 不,这是不可能的,因为这是多态性与指向成员方法的指针结合的方式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM