是否可以在lambda中捕获可变数量的参数? [英] Is it possible to capture a variable number of parameters in a lambda?

查看:473
本文介绍了是否可以在lambda中捕获可变数量的参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑以下一组示例。

Consider the following set of examples.


  1. 函数 takeOnlyVoidFunction 使用零参数的函数,只是执行它。

  2. 函数 takeVariableArguments 采用可变数量的参数,并使用参数执行函数。

  3. 函数 captureVariableArgs 尝试将第二个函数转换为第一个函数可接受的lambda形式,但它不编译。

  1. The function takeOnlyVoidFunction takes a function with zero arguments and simply executes it.
  2. The function takeVariableArguments takes a variable number of arguments and executes the function using the arguments.
  3. The function captureVariableArgs attempts to convert the second function into a lambda form that is acceptable by the first function, but it does not compile.

如何使函数 captureVariableArgs 将具有可变数量参数的函数转换为没有参数的闭包的正确行为?

How can I make the function captureVariableArgs compile and exhibit the correct behavior of converting a function with a variable number of arguments into a closure with no arguments?

#include <stdio.h>
#include <functional>

void takeOnlyVoidFunction(std::function<void()> task) {
    task();
}

template<typename _Callable, typename... _Args>
    void takeVariableArguments(_Callable&& __f, _Args&&... __args) {
     __f(__args...);
}

// How can I make this function compile?
template<typename _Callable, typename... _Args>
    void captureVariableArgs(_Callable&& __f, _Args&&... __args) {
    takeOnlyVoidFunction([=]() { __f(__args...);});
}

void normalFunction(int a, int b) {
    printf("I am a normal function which takes params (%d,%d)\n", a, b);
}

int main() {
    int a = 7;
    int b = 8;
    takeVariableArguments(normalFunction, a, b);
    takeOnlyVoidFunction([=](){ normalFunction(a,b);});
    captureVariableArgs(normalFunction, a, b);
}

我正在运行 gcc 4.9.2 。这是我看到的编译器错误。

I'm running gcc 4.9.2. Here is the compiler error I see.

g++ -std=c++11    Test.cc   -o Test
Test.cc: In instantiation of ‘captureVariableArgs(_Callable&&, _Args&& ...)::<lambda()> [with _Callable = void (&)(int, int); _Args = {int&, int&}]’:
Test.cc:16:38:   required from ‘struct captureVariableArgs(_Callable&&, _Args&& ...) [with _Callable = void (&)(int, int); _Args = {int&, int&}]::<lambda()>’
Test.cc:16:50:   required from ‘void captureVariableArgs(_Callable&&, _Args&& ...) [with _Callable = void (&)(int, int); _Args = {int&, int&}]’
Test.cc:28:45:   required from here
Test.cc:16:34: error: variable ‘__f’ has function type
     takeOnlyVoidFunction([=]() { __f(__args...);});
                                  ^
Test.cc:16:34: error: variable ‘__f’ has function type
Test.cc: In instantiation of ‘struct captureVariableArgs(_Callable&&, _Args&& ...) [with _Callable = void (&)(int, int); _Args = {int&, int&}]::<lambda()>’:
Test.cc:16:50:   required from ‘void captureVariableArgs(_Callable&&, _Args&& ...) [with _Callable = void (&)(int, int); _Args = {int&, int&}]’
Test.cc:28:45:   required from here
Test.cc:16:34: error: field ‘captureVariableArgs(_Callable&&, _Args&& ...) [with _Callable = void (&)(int, int); _Args = {int&, int&}]::<lambda()>::<__f capture>’ invalidly declared function type
In file included from Test.cc:2:0:
/usr/include/c++/4.9/functional:2418:7: error: ‘std::function<_Res(_ArgTypes ...)>::function(_Functor) [with _Functor = captureVariableArgs(_Callable&&, _Args&& ...) [with _Callable = void (&)(int, int); _Args = {int&, int&}]::<lambda()>; <template-parameter-2-2> = void; _Res = void; _ArgTypes = {}]’, declared using local type ‘captureVariableArgs(_Callable&&, _Args&& ...) [with _Callable = void (&)(int, int); _Args = {int&, int&}]::<lambda()>’, is used but never defined [-fpermissive]
       function<_Res(_ArgTypes...)>::
       ^






更新 :一个更小的示例演示这个问题。


Update: A more minimal example demonstrating this problem.

#include <stdio.h>

// How can I make this function compile?
template<typename _Callable>
void captureVariableArgs(_Callable&& __f) {
    takeOnlyVoidFunction( [=]{ __f(); } );
}

void normalFunction() {
    printf("I am a normal function\n");
}

int main(){
    captureVariableArgs(normalFunction);
}


推荐答案

,而不是使用lambda,您可以使用 std :: bind

As another potential workaround for GCC, instead of using a lambda, you could use std::bind:

template <typename F, typename... Args>
auto captureVariable(F&& f, Args&&... args)
{
    return std::bind(std::forward<F>(f), std::forward<Args>(args)...);
}

这适用于GCC 4.9.3下的我。

This works for me under GCC 4.9.3.

这篇关于是否可以在lambda中捕获可变数量的参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆