Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/132.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++ 通过lambda函数转发附加参数_C++_C++11_Lambda - Fatal编程技术网

C++ 通过lambda函数转发附加参数

C++ 通过lambda函数转发附加参数,c++,c++11,lambda,C++,C++11,Lambda,这是最小可复制代码 #include <iostream> #include <string> void bar(std::string s, int x){ std::cout <<std::endl<< __FUNCTION__<<":"<<s<<" "<<x; } using f_ptr = void(*)(std::strin

这是最小可复制代码

#include <iostream>
#include <string>

void bar(std::string s, int x){        
    std::cout <<std::endl<< __FUNCTION__<<":"<<s<<" "<<x;
}

using f_ptr = void(*)(std::string);


void foo(f_ptr ptr){        
    ptr("Hello world");
}


template<typename T> void fun(T f){
        static int x;
        std::cout <<std::endl<<x++<<std::endl;
        f("Hello World");
}

int main()
{    
    //case:1
    f_ptr ptr1 = [](std::string s){bar(s,10);}; 
   // foo(ptr1);
    
    //case:2
    static int x =10;
    f_ptr ptr2 = [x](std::string s){bar(s,x);}; 
    //foo(ptr2); 
    
    
    //case:3
    int y =10;
    f_ptr ptr3 = [y](std::string s){bar(s,y);}; /* error*/
    foo(ptr3); 
    
    //case:4
    int z = 12;
    fun([z](std::string s){bar(s,z);});
    
    return 0;
}
我的问题是,

  • 有没有办法通过lambda转发额外的参数,比如
    case:3
  • 案例3
    中,什么转换导致错误
  • 案例:4
    中,
    类型名T
    被推断为什么
  • 有没有办法通过lambda转发额外的参数,比如
    case:3
  • 案例3
    中,什么转换导致错误
  • 带有捕获列表的lambda无法隐式转换为函数指针;没有俘获的兰博达斯可以。您可以使用
    std::function

    void foo(std::function<void(std::string)> f){        
        f("Hello world");
    }
    
    voidfoo(std::函数f){
    f(“你好世界”);
    }
    
    或者像
    fun
    那样直接使用lambda

  • 案例:4
    中,
    类型名T
    被推断为什么

  • 该类型将是唯一的闭包类型;lambda表达式是该类型的prvalue表达式。

    一些详细信息,为什么会编译而案例3不会编译:

    //case:2
    static int x =10;
    f_ptr ptr2 = [x](std::string s){bar(s,x);}; 
    
    它可以编译,因为它实际上不捕获任何内容,因此lambda可以绑定到函数指针,这在有效捕获情况下是不允许的。标准上说:

    5.1.1/2 lambda捕获中的名称应在lambda表达式的上下文范围内,且应为该名称或引用本地名称 具有自动存储持续时间的变量或引用

    因此,静态变量捕获情况的行为至少没有指定,但不一定是未定义的行为(实现的自由度)

    请注意,捕获静态变量可能会导致令人生疑的可怕问题,因为从捕获列表的语义中可能需要复制值,但实际上没有复制任何内容


    还要注意的是,这个问题对于全局变量也是一样的(没有自动存储持续时间)

    在案例2中,您没有捕获任何内容,因此
    [x]
    应该只是
    []
    (基本上与案例1相同),而在案例3中,lambda对象无法转换为指向普通函数的指针,因为它具有数据成员
    y
    。在情况4中,T被推断为lambda的一种类型。
    //case:2
    static int x =10;
    f_ptr ptr2 = [x](std::string s){bar(s,x);};