【问题标题】:How to convert an object and its method into a function callable just with method’s arguments如何将对象及其方法转换为仅使用方法参数即可调用的函数
【发布时间】:2021-05-04 15:26:02
【问题描述】:

有一个功能

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, typename MemberFuncPtr>
auto makeCallback( Class* a, MemberFuncPtr func )
{
    return [a, 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( &amp;d, &amp;Base::g ),程序仍会打印“Derived”。

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

【问题讨论】:

  • 虚函数就是这样工作的。通过“指向虚拟成员函数的指针”的调用是虚拟调用。
  • 你可以通过(&amp;d)-&gt;Base::g(1, 2)调用Base方法但是我不确定是否可以模板化。
  • 你为什么要那个?这几乎总是一个错误。
  • 我只想要一个简单的方法来将特定对象方法的调用转换为可调用函数。如果我可以直接调用任何方法,包括父类中的方法,为什么会出错。

标签: c++ lambda polymorphism pointer-to-member


【解决方案1】:

您可能会这样做,但需要一些更改:

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

【讨论】:

    猜你喜欢
    • 2015-08-10
    • 2018-02-05
    • 1970-01-01
    • 1970-01-01
    • 2021-03-11
    • 2018-04-13
    • 2015-06-23
    • 1970-01-01
    • 2012-06-22
    相关资源
    最近更新 更多