C++;lambda to std::函数错误,包含非常量字符串 以下的代码给出C++ 11中的错误: function<bool(string,string)> comp = [] (string& s1, string& s2) {return s1.length() > s2.length(); }; 函数comp=[](string&s1,string&s2){返回s1.length()>s2.length();};

C++;lambda to std::函数错误,包含非常量字符串 以下的代码给出C++ 11中的错误: function<bool(string,string)> comp = [] (string& s1, string& s2) {return s1.length() > s2.length(); }; 函数comp=[](string&s1,string&s2){返回s1.length()>s2.length();};,c++,c++11,lambda,C++,C++11,Lambda,但这并不是: function<bool(string,string)> comp = [] (const string& s1, const string& s2) {return s1.length() > s2.length(); }; 函数comp=[](常量字符串&s1,常量字符串&s2){返回s1.length()>s2.length();}; 第二个调用具有常量in参数。有什么解释吗?这与lambdas没有任何关系。当您将函数声明为接受常量引用

但这并不是:

function<bool(string,string)> comp = [] (const string& s1, const string& s2) {return s1.length() > s2.length(); };
函数comp=[](常量字符串&s1,常量字符串&s2){返回s1.length()>s2.length();};

第二个调用具有常量in参数。有什么解释吗?

这与lambdas没有任何关系。当您将函数声明为接受常量引用时,您将激活

允许-包含hello的字符串的生存期在执行
foo
期间延长

对于非常量引用,没有此类扩展规则,因此编译器将不允许:

bar(std::string("farewell")); 

因为如果它这样做了,在
foo
开始的时候,它只会引用曾经是告别字符串的被破坏的残余部分。

它实际上与lambdas没有任何关系。当您将函数声明为接受常量引用时,您将激活

允许-包含hello的字符串的生存期在执行
foo
期间延长

对于非常量引用,没有此类扩展规则,因此编译器将不允许:

bar(std::string("farewell")); 

因为如果它这样做了,在
foo
开始时,它将只引用曾经是告别字符串的被破坏的残余部分。

来自C++11标准§20.8.11.2:

格式良好,其中
f
是lambda,
declval
表示
string
类型的右值对象。由于右值不能绑定到非常量左值引用,因此此处不满足此条件


相反,右值可以绑定到常量左值引用,因此第二种情况是可以的。

来自C++11标准§20.8.11.2:

格式良好,其中
f
是lambda,
declval
表示
string
类型的右值对象。由于右值不能绑定到非常量左值引用,因此此处不满足此条件

相反,右值可以绑定到常量左值引用,因此第二种情况是可以的。

在第一种情况下

function<bool(string,string)> comp = [] (string& s1, string& s2) {return s1.length() > s2.length(); };
这里的错误是您试图获取对右值的非常量左值引用,这违反了标准

修复解决方案1,使用
函数
(我认为您可能正在尝试使用此版本):

函数comp=[](string&s1,string&s2){返回s1.length()>s2.length();};
固定溶液2,使用右值参考:

function<bool(string,string)> comp = [] (string&& s1, string&& s2) {return s1.length() > s2.length(); };
函数comp=[](字符串和&s1,字符串和&s2){返回s1.length()>s2.length();};
在你的第二个案例中

function<bool(string,string)> comp = [] (const string& s1, const string& s2) {return s1.length() > s2.length(); };
函数comp=[](常量字符串&s1,常量字符串&s2){返回s1.length()>s2.length();};
您正试图获取对右值的常量左值引用,这不违反任何标准。

在第一种情况下

function<bool(string,string)> comp = [] (string& s1, string& s2) {return s1.length() > s2.length(); };
这里的错误是您试图获取对右值的非常量左值引用,这违反了标准

修复解决方案1,使用
函数
(我认为您可能正在尝试使用此版本):

函数comp=[](string&s1,string&s2){返回s1.length()>s2.length();};
固定溶液2,使用右值参考:

function<bool(string,string)> comp = [] (string&& s1, string&& s2) {return s1.length() > s2.length(); };
函数comp=[](字符串和&s1,字符串和&s2){返回s1.length()>s2.length();};
在你的第二个案例中

function<bool(string,string)> comp = [] (const string& s1, const string& s2) {return s1.length() > s2.length(); };
函数comp=[](常量字符串&s1,常量字符串&s2){返回s1.length()>s2.length();};

您正在尝试获取对右值的常量左值引用,这不违反任何标准。

临时对象或文本不能绑定到对非常量对象的引用。应该告诉过你的。右值(如通过值传递的参数)不能绑定到非常量左值引用,但可以绑定到常量左值引用。你知道自动对lambda有效吗<代码>自动编译=…临时对象或文字不能绑定到对非常量对象的引用。应该告诉过你的。右值(如通过值传递的参数)不能绑定到非常量左值引用,但可以绑定到常量左值引用。你知道自动对lambda有效吗<代码>自动补偿=…
function<bool(string,string)> comp = [] (const string& s1, const string& s2) {return s1.length() > s2.length(); };