c – 在lambda上使用条件运算符调用std :: any_of会产生意外结果
作者:互联网
这是我最近在VS2012中编写的一些代码:
///<summary>Lambda: Returns true if the field is significant within a baseline context</summary>
const auto IsSignificantBaselineField = [](const field_info & field)->bool
{
//Some lines removed here!
return something;
};
///<summary>Lambda: Returns true if the field is significant within a project context</summary>
const auto IsSignificantProjectField = [&IsSignificantBaselineField](const field_info & field)->bool
{
if (!IsSignificantBaselineField (field))
return false;
//Some lines removed here!
return something_else;
};
return std::any_of (modified_fields.begin (), modified_fields.end (), (proj_id == 0) ? IsSignificantProjectField : IsSignificantBaselineField);
奇怪的是,当’proj_id = 90000’时,std :: any_of正在调用IsSignificantProjectField,而我的意图是在这种情况下将调用IsSignificantBaselineField.
请问任何人可以解释我逻辑中的错误吗?
解决方法:
所以这是我的猜测为什么代码编译并显示您观察到的行为.
lambdas都由编译器转换为结构.
一个没有捕获,因此没有成员和一个no-arg构造函数.
struct IsSignificantBaselineField_Lambda {
bool operator ()(const field_info & field) { ... }
};
另一个有一个捕获,转换为一个成员和一个单arg构造函数.
struct IsSignificantProjectField_Lambda {
IsSignificantProjectField_Lambda(IsSignificantBaselineField_Lambda& capture1)
: m_capture1(capture1) {}
bool operator ()(const field_info & field) {
if (!m_capture1(field)) return false;
...
}
private:
IsSignificantBaselineField_Lambda& m_capture1;
};
我敢打赌,编译器的转换不会使该构造函数显式化,从而使其成为转换构造函数,这意味着IsSignificantBaselineField可以转换为IsSignificantProjectField,因此IsSignificantProjectField是两者的通用类型.所以这个电话相当于:
return std::any_of (modified_fields.begin (), modified_fields.end (),
(proj_id == 0) ? IsSignificantProjectField :
IsSignificantProjectField_Lambda(IsSignificantBaselineField));
实际效果是两个分支都做同样的事情.
这当然是编译器错误.
标签:c,c11,lambda,conditional-operator,c-standard-library 来源: https://codeday.me/bug/20190723/1509423.html