【问题标题】:convert void* stored in std::vector to function arguments using variadic templates使用可变参数模板将存储在 std::vector 中的 void* 转换为函数参数
【发布时间】:2014-05-09 18:52:21
【问题描述】:

我创建了一个存储函数及其参数类型的 MemberFunctionWrapper 模板类。它有一个 call 方法,它接受一个 void* 向量,并在调用函数之前将它们转换为函数调用所需的参数类型。

我的问题是包装器只能接受固定数量的函数参数 (_arg0, _arg1)。
我希望该类采用任意数量的函数参数(arg0、arg1、arg2 ... argX)我该如何实现?

提前致谢

class Foo
{
public:
    void foo( int a, const string& b );
};

template< class _obj, class _function, class _arg0, class _arg1 >
class MemberFunctionWrapper
{
    const _function m_memberfunction;

public:
    MemberFunctionWrapper( _function memFn )
        : m_memberfunction( memFn )
    { }

    void call( std::shared_ptr<void>& obj,
               const std::vector<std::shared_ptr<void>>& args )
    {
        m_memberfunction( *static_cast< _obj* >(obj.get()),
                          *static_cast< _arg0* >(args.at( 0 ).get()),
                          *static_cast< _arg1* >(args.at( 1 ).get()) );
    }

};

int main()
{
    std::shared_ptr<int> i( new int( 88 ) );
    std::shared_ptr<string> s( new string( "hello" ) );
    std::shared_ptr<Foo> foo( new Foo );

    std::shared_ptr<void> iVoid = std::static_pointer_cast< void >(i);
    std::shared_ptr<void> sVoid = std::static_pointer_cast< void >(s);
    std::shared_ptr<void> fooVoid = std::static_pointer_cast< void >(foo);

    MemberFunctionWrapper
    <
        Foo,
        decltype(std::mem_fn( &Foo::foo )),
        int,
        string
    > wrapper( &Foo::foo );

    wrapper.call( fooVoid, std::vector<std::shared_ptr<void>>{iVoid, sVoid} );

    system( "pause" );
}

【问题讨论】:

    标签: templates c++11 variadic-templates void-pointers


    【解决方案1】:

    以下可能会有所帮助:https://ideone.com/l7yAJN

    template<typename F> class MemberFunctionWrapper;
    
    template<class Obj, class Ret, typename ... Args>
    class MemberFunctionWrapper<Ret (Obj::*)(Args...)>
    {
        typedef Ret (Obj::*MemberFunction)(Args...);
        const MemberFunction m_memberfunction;
    
        template <std::size_t ... Is>
        void call(std::shared_ptr<void>& obj,
                  const std::vector<std::shared_ptr<void>>& args,
                  index_sequence<Is...>)
          {
              (static_cast<Obj*>(obj.get())->*m_memberfunction)
                  (*static_cast<typename std::remove_reference<Args>::type*>(args.at(Is).get())...);
          }
    public:
        MemberFunctionWrapper(MemberFunction memFn) : m_memberfunction(memFn)
        {}
    
        void call(std::shared_ptr<void>& obj,
                  const std::vector<std::shared_ptr<void>>& args )
        {
            assert(args.size() == sizeof...(Args));
            call(obj, args, make_index_sequence<sizeof...(Args)>());
        }
    
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多