使用std :: function和template参数将函数传递给函数

问题描述

我试图将指向谓词函数的指针传递到FooBar函数中。 Bar函数正常运行,但是Foo函数引发编译时错误

错误:没有匹配的函数可以调用Foo<int>(bool (&)(int))

为什么编译器会引发错误Foo的解压缩之后,BarArgs的模板参数类型之间有什么区别吗?

#include <functional>

bool predicate(int a) {
    return (a > 5);
}

// sizeof...(Args) == 1 and I suppose it is int
template<typename... Args>
void Foo(std::function<bool(Args...)> predicate) {
    // clang: note: candidate template ignored:
    //        Could not match 'function<bool (int,type-parameter-0-0...)>' 
    //        against 'bool (*)(int)'
}

template<typename Args>
void Bar(std::function<bool(Args)> predicate) {

}

int main(int argc,char const *argv[]) {
    // gcc: error: no matching function for call to
    //      'Foo<int>(bool (&)(int))'
    Foo<int>(predicate);
    Bar<int>(predicate);
    
    return 0;
}

See Compiler Explorer for a live example

我还尝试了一点Foo函数的更改,并且它以某种方式起作用:

template<typename... Args>
void Foo(bool(*predicate)(Args...)) {
  std::function<bool(Args...)> func(predicate);
}

我想在std::function函数中使用Foo类型的参数,但是我不知道该怎么做

解决方法

该错误是因为std::function的确切类型与predicate不同。要解决此问题,您可以显式调用std::function的构造函数:

int main() {
    Foo<int>( std::function<bool(int){predicate} );
    //OR
    Foo<int>( {predicate} );
    return 0;
}