函数和仿函数作为模板函数的参数

pas*_*cal 2 c++ templates function-pointers

我正在寻找一种方法将函数指针,仿函数或lambda传递给g使用传递函数的参数类型的模板函数,例如:

template<class T1, class T2, class T3>
struct wrapper_t {
  boost::function<void(T1,T2,T3)> f;
  wrapper_t( boost::function<void(T1,T2,T3)> f ) : f(f) {}
  void operator( std::vector<T1> &a, std::vector<T2> &b, T3 c ) {
    assert(a.size() == b.size());
    for(size_t i = 0 ; i != a.size() ; i++) f(a[i], b[i], c);
  }
};
template<class T1, class T2, class T3>
wrapper_t<T1,T2,T3> make_wrapper( boost::function<void(T1,T2,T3)> f ) {
  return wrapper_t<T1,T2,T3>( f );
}

void f(int, double, char) {};
wrapper_t<int, double, char> w0(f); // need to repeat types

auto w1 = make_wrapper(f); // more comfortable

std::vector<int> a{{1, 2, 3}};
std::vector<double> b{{1.0, 2.0, 3.0}};
w0( a, b, 'c' );
w1( a, b, 'c' );
Run Code Online (Sandbox Code Playgroud)

make_wrapper函数仅用于从参数中提取类型,一些语法糖以避免必须两次输入.


我的问题的一个最小例子就是这个函数:

template<class T>
void g1( const boost::function<void(T)> & ) {}
Run Code Online (Sandbox Code Playgroud)

使用这些作为输入

void f1(int) {}
struct f2_t { void operator()(int) {} };
Run Code Online (Sandbox Code Playgroud)

它无法推断 T=int

f2_t f2;
g1( f1 ); // mismatched types ‘const std::function<void(T)>’ and ‘void(int)’
g1( f2 ); // ‘f2_t’ is not derived from ‘const std::function<void(T)>’
g1( [](int){} ); // ‘::<lambda(int)>’ is not derived from ‘…
g1<int>( f1 ); // ok
g1<int>( f2 ); // ok
g1<int>( [](int){} ); // ok
Run Code Online (Sandbox Code Playgroud)

但是T=int可以从普通的函数指针推断,但是这对于函数或lambda也不起作用:

template<class T>
void g2( void (*)(T) ) {}

g2( f1 ); // ok
g2( f2 ); // mismatched types …
g2<int>( f2 ); // ok
g2( [](int){} ); // mismatched types …
g2<int>( [](int){} ); // ok
Run Code Online (Sandbox Code Playgroud)

有没有办法不仅可以推断T普通函数指针,还可以推断函子和lambdas?

或者它必须是这样的?

template<class F>
void g( F ) { typedef first_argument_of<F>::type T; }
Run Code Online (Sandbox Code Playgroud)

(在我的实际代码中,我需要以这种方式解析一个带有四个参数的函数,但std::function::…argument_type只存在一个或两个参数; boost::function有argN_type,但我认为无论如何我都不能使用它,因为F并不总是function这是我的问题,见上面等)

K-b*_*llo 5

由于各种原因,没有办法做你想做的事.但是这里应该让问题非常明确:

struct function_object
{
    template<typename ...T>
    void operator ()(T&&... v){}
};

f( function_object{} );
Run Code Online (Sandbox Code Playgroud)

传递给的函数对象的参数类型是什么f?没有任何,它可以用任何种类和数量的参数调用.

  • 换句话说,对于支持这种语言的语言,它需要明确地将其添加为规则的例外,从语言设计的角度来看这也是不可取的,但从用户的角度来看也是如此(你的语言规则越多)更难以推断你在其中编写的程序. (2认同)