可变参数模板lambda参数的模板推导

时间:2017-02-13 02:51:22

标签: c++ templates lambda

给出以下可变参数模板:

template<typename... Params>
void fun(void(*f)(Params...), Params... params) {
  f(params...);
}

int main() {
  fun(+[](int a, int b) {}, 2, 3);
}

现在,当使用lambda调用fun时,我需要明确指定所有lambda参数的类型。这似乎是多余的,因为int, int可以从2, 3推断出来。有没有办法让它更简洁自动?

我希望以下内容有效,但事实并非如此:

template<typename... Params>
void fun(void(*f)(Params...), Params... params) {
  f(params...);
}

int main() {
  fun(+[](auto a, auto b) {}, 2, 3);
}

我正在使用g++ 5.4.0-std=c++14进行编译。

1 个答案:

答案 0 :(得分:3)

T而不是指针:

取得函数
template<typename T, typename... Params>
void fun(T f, Params... params) {
  f(params...);
}

int main() {
  fun([](auto a, auto b) {}, 2, 3);
}

这样,编译器可以选择在调用站点调用哪个重载,而不是在+运算符内。正如评论中所述,无论如何都没有为通用lambdas定义+运算符。

或者,您可以禁止编译器尝试使用标识别名从函数指针中推导出Params,但我确实不推荐它。无论如何,你走了:

template<typename T>
struct identity { using type = T; };

template<typename T>
using identity_t = typename identity<T>::type;

template<typename... Params>
void fun(void(*f)(identity_t<Params>...), Params... params) {
  f(params...);
}

int main() {
  //  v----- no unary +. That operator is not defined for generic lambdas.
  fun([](auto a, auto b) {}, 2, 3);
}