Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/145.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;11 lambdas到函数指针_C++_C++11 - Fatal编程技术网

C++ C++;11 lambdas到函数指针

C++ C++;11 lambdas到函数指针,c++,c++11,C++,C++11,我开始使用C++11 lambdas开发应用程序,需要将一些类型转换为函数指针。这在GCC 4.6.0中非常有效: void (* test)() = []() { puts("Test!"); }; test(); 我的问题是当我需要在lambda中使用函数或方法局部变量时: const char * text = "test!"; void (* test)() = [&]() { puts(text); }; test(); G++4.6.0给出了强制转换

我开始使用C++11 lambdas开发应用程序,需要将一些类型转换为函数指针。这在GCC 4.6.0中非常有效:

void (* test)() = []()
{
    puts("Test!");
};

test();
我的问题是当我需要在lambda中使用函数或方法局部变量时:

const char * text = "test!";

void (* test)() = [&]()
{
    puts(text);
};

test();
G++4.6.0给出了强制转换错误代码:

main.cpp: In function 'void init(int)':
main.cpp:10:2: error: cannot convert 'main(int argc, char ** argv)::<lambda()>' to 'void (*)()' in initialization

我的问题是:如何使用[&]为lambda创建类型?在我的例子中,我不能使用STL>强> STD::函数< /St>(因为我的程序不使用C++ RTTI和异常运行时),它有一个简单的函数来解决这个问题。

< P>可以使用<代码> STD::函数< /> >,不需要任何“运行时”。否则,.

只有没有捕获的lambda才能转换为函数指针。这是lambdas的扩展,仅适用于此特定情况[*]。通常,lambda是函数对象,不能将函数对象转换为函数

具有状态(捕获)的lambda的替代方法是使用
std::function
,而不是普通的函数指针


[*]:如果保存状态的lambda可以转换为函数指针,那么状态将保留在哪里?(请注意,此特定lambda可能有多个实例,每个实例都有自己的状态,需要单独维护)

<>我不能使用STL STD::For函数(因为我的程序不使用C++ RTTI和异常运行时)

然后您可能需要编写自己的等价于
std::function

std::function
的类型擦除的通常实现不需要RTTI来实现其大部分功能;它通过常规的虚拟函数调用工作。因此,编写自己的版本是可行的

实际上,
std::function
中唯一需要RTTI的是
target\u类型
target
函数,它们不是世界上最有用的函数。假设您正在使用的实现不需要RTTI来完成其日常业务,那么您可能只需要使用
std::function
,而不需要调用这些函数


通常,当您禁用异常处理时,当遇到
throw
语句时,程序会简单地关闭并出错。由于
std::function
会发出的大多数异常都不是您能够从中恢复的(调用空
函数、内存不足等),因此您可能只需按原样使用
std::function

如前所述,只有不捕获任何内容的lambda才能转换为函数指针

如果您不想使用或编写类似std::function的东西,那么另一种选择是将您本来可以捕获的东西作为参数传递。您甚至可以创建一个结构来保存它们

#include <iostream>

struct captures { int x; };
int (*func)(captures *c) = [](captures *c){ return c->x; };

int main() {
    captures c = {10};

    std::cout << func(&c) << '\n';
}
#包括
结构捕获{int x;};
int(*func)(捕获*c)=[](捕获*c){返回c->x;};
int main(){
捕获c={10};

std::cout我不能使用std::function,因为我的代码需要RTTI,并且禁用了异常。听起来像的实例。您无法将捕获lambda转换为函数指针。请解释您试图执行的操作。您已经解释过了(很糟糕)一个尝试性的解决方案,但没有描述您的实际问题是什么。请告诉我们您的实际问题是什么is@Antonio:在查看了
std::function
的一个实现之后,我对我的答案做了一些更正。您可能应该看一看。这是否回答了您的问题?如果您按如下
常量这样的值传递它这是一个很有意义的例子。它取决于,请考虑<代码> STD::函数f(int x){const int c= x;返回[c](int i){返回i*c;}
f
返回的函子依赖于它的参数,因此具有状态。只有当捕获是一个常量表达式时,它才能分解为一个普通函数。嗯,我部分同意。它仍然可以实现,但解决方案可能会很昂贵,因为程序每次都需要用它复制lambda函数的代码在函数代码中更改C的值。(或者,如果不复制函数的整个代码,则需要进行计划跳跃,其中跳转可以使事情慢下来。)@ BnabasasZrcCs:我不认为这是可以完成的,考虑到函数的参数可以是运行时值(例如从用户输入中读取)。您不能基于运行时值创建函数。您可以想象将该值存储在一边,但要确保不同的lambda在创建新lambda时不会被破坏,这反过来又需要动态内存,而动态内存的使用对于编译器来说是难以解决的…在VS2013和xcode6.lambda上都尝试过,但没有capture可以转换为函数指针,谢谢大家的指点。
#include <iostream>

struct captures { int x; };
int (*func)(captures *c) = [](captures *c){ return c->x; };

int main() {
    captures c = {10};

    std::cout << func(&c) << '\n';
}