Eug*_*yev 16 c++ lambda templates metaprogramming function
考虑下一个代码示例:
template <typename... TArgs>
void foo(std::function<void(TArgs...)> f) {
}
template <typename... TArgs>
class Class {
public:
static void foo(std::function<void(TArgs...)> f) {
}
};
Run Code Online (Sandbox Code Playgroud)
为什么我可以这样做:
int main() {
// Helper class call
Class<int, int>::foo(
[](int a, int b) {}
);
}
Run Code Online (Sandbox Code Playgroud)
但这样做时出现编译错误:
int main() {
// Function call
foo<int, int>(
[](int a, int b) {}
);
}
Run Code Online (Sandbox Code Playgroud)
<source>:16:5: error: no matching function for call to 'foo'
foo<int, int>(
^~~~~~~~~~~~~
<source>:4:6: note: candidate template ignored: could not match
'std::function<void (int, int, TArgs...)>' against
'(lambda at <source>:17:9)'
void foo(std::function<void(TArgs...)> f) {
^
Run Code Online (Sandbox Code Playgroud)
我只是想有一种方便的方式来使用诸如foo.
我试过这个:
std::function<void(int, int)> f = [](int a, int b) {
};
foo<int, int>(f); // ok
Run Code Online (Sandbox Code Playgroud)
它奏效了。这没关系。但我想知道是否有任何方法可以在函数调用中使用 lambda,而不创建本地函数对象。
Art*_*yer 17
因此:为什么在函数参数类型中使用模板参数包,因为它的模板参数列表无法显式指定
当您调用 时foo<int, int>([](int a, int b) {});,仍会扣除该包TArgs,以防需要扩展。无法使用 lambda 参数std::function<void(TArgs...)>推导出任何内容,因此它被推导为空包,这与给定的.TArgs...int, int
对于Class<int, int>::foo,没有模板参数推导,因为模板参数已经给出。
解决这个问题的方法是将其放在非推导的上下文中:
template <typename... TArgs>
void foo(std::type_identity_t<std::function<void(TArgs...)>> f) {
}
Run Code Online (Sandbox Code Playgroud)
std::function或者根本不采取:
template <typename F>
void foo(F&& f) {
}
Run Code Online (Sandbox Code Playgroud)