如何将对象及其方法转换为仅使用方法参数即可调用的函数

问题描述

一个功能

template<typename Class,typename MemberFuncPtr>
auto makeCallback( Class* a,MemberFuncPtr func )
{
    return [a,func]( auto&&... args )
    {
        return ( a->*func )( std::forward<decltype( args )>( args )... );
    };
}

将对象指针及其成员方法转换为捕获它们的 lambda,稍后只需使用方法的参数即可调用它们。 它工作正常,除了一种情况,其中方法是虚拟的并在派生类中被覆盖,例如

#include <iostream>

struct Base
{
    virtual void g( int,int ) const
    {
        std::cout << "Base" << std::endl;
    }
};

struct Derived : Base
{
    virtual void g( int,int ) const override
    {
        std::cout << "Derived" << std::endl;
    }
};

template<typename Class,func]( auto&&... args )
    {
        return ( a->*func )( std::forward<decltype( args )>( args )... );
    };
}

int main()
{
    Derived d;
    auto cb = makeCallback( &d,&Base::g );
    cb( 1,2 );

    return 0;
}

这里尽管 makeCallback( &d,&Base::g ) 程序打印了“Derived”。

有没有办法只修改 makeCallback包括其签名的任何更改)以在程序输出中接收“Base”?

解决方法

你可能会这样做,但需要做一些改变:

template<typename Class,typename MemberFuncPtr>
auto makeCallback( Class* a,MemberFuncPtr func )
{
    return [a,func]( auto&&... args )
    {
        return std::invoke(func,a,std::forward<decltype( args )>( args )... );
    };
}

int main()
{
    Derived d;
    auto cb = makeCallback(&d,[](auto obj,auto&&... args){ obj->Base::g(args...); });
    cb( 1,2 );
}

Demo

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...