C++11 Template function that takes a std::function which depends of template parameters

前端 未结 3 929
北海茫月
北海茫月 2020-12-18 07:11

I am trying to write a template function that accepts a std::function which depends on the template arguments. Unfortunately the compiler is not capable of corr

相关标签:
3条回答
  • 2020-12-18 07:32

    If you are using templates, you can avoid std::function entirely, unless for some reason you want to specifically restrict the function to take std::function:

    template < typename Ident, typename Param, typename Func >
    void CallFunc( Ident ident, Param param, Func op )
    {
        op( ident, param );
    }
    
    0 讨论(0)
  • 2020-12-18 07:45

    You can do the conversion inline or use bind. Neither is particularly pretty, but they get the job done:

    CallFunc(id, param, std::function<void(unsigned, unsigned)>(DoSomething));
    

    CallFunc(id, param, std::bind(DoSomething, std::placeholders::_1, std::placeholders::_2));
    

    0 讨论(0)
  • 2020-12-18 07:48

    You need to make the third function parameter a non-deduced context for the template parameters therein. Then the compiler will not compare the argument type against the parameter type without also considering all implicit conversions (the Standard says, and C++0x clarified this further, that for a function parameter where there are no template parameters in deducing positions, all implicit conversions are allowed in bridging a difference).

    template < typename T > struct id { typedef T type; };
    
    template < typename Ident, typename Param >
    void CallFunc( Ident ident, Param param, 
                   typename id<std::function< void ( Ident, Param ) >>::type op )
    {
        op( ident, param );
    }
    

    Instead of id you can use boost::identity. In C++0x and compilers that support it, you can have a more readable edition using alias templates

    template < typename T > using nondeduced = typename id<T>::type;
    

    Then your code becomes simply

    template < typename Ident, typename Param >
    void CallFunc( Ident ident, Param param, 
                   std::function< nondeduced<void ( Ident, Param )> > op )
    {
        op( ident, param );
    }
    

    However GCC does not yet support alias templates.

    0 讨论(0)
提交回复
热议问题