3

这是我最近在 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。

请任何人都可以解释我的逻辑中的错误吗?

4

1 回答 1

9

所以这是我的猜测,为什么代码会编译并显示您观察到的行为。

lambdas 都被编译器转换为结构。

一个没有捕获,因此没有成员和无参数构造函数。

struct IsSignificantBaselineField_Lambda {
  bool operator ()(const field_info & field) { ... }
};

另一个有一个捕获,转换为一个成员和一个单参数构造函数。

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;
};

我敢打赌,编译器的转换不会使构造函数explicit成为转换构造函数,这意味着 IsSignificantBaselineField 可以转换为 IsSignificantProjectField,因此 IsSignificantProjectField 是两者的通用类型。所以调用相当于:

return std::any_of (modified_fields.begin (), modified_fields.end (),
    (proj_id == 0) ? IsSignificantProjectField :
                     IsSignificantProjectField_Lambda(IsSignificantBaselineField));

最终结果是两个分支都做同样的事情。

这当然是一个编译器错误。

于 2013-06-13T12:33:36.893 回答