3

를 제공입니다 : 'PROJ_ID = 90000', IsSignificantProjectField이 표준에 의해 호출되고 이상하게호출 표준 : 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); 

을 :: any_of,이 경우에는 IsSignificantBaselineField가 호출 될 것이라는 의도가 있습니다.

누구든지 내 논리에서 잘못을 설명 할 수 있습니까?

+2

이 컴파일됩니까? 그렇게해서는 안됩니다. 두 람다 유형 간에는 일반적인 유형이 없습니다. –

+0

그래, 그것은 VS2012에서 깨끗하게 컴파일됩니다. 공통된 유형이 없다는 것이 나에게는 발생하지 않았지만, 그것은 나에게 합리적으로 들린다. –

+0

사무실의 누군가가 기본 콘솔 응용 프로그램에서 비슷한 것을 시도했지만 컴파일되지 않습니다. 필자는 컴파일러에 약간의 미묘한 버그가있어 내 경우에는 컴파일 할 수 있지만 작동하지는 않는다고 생각합니다. –

답변

9

그래서 여기에 코드가 컴파일되고 관찰 한 동작을 보여주는 것으로 추측됩니다.

람다는 모두 컴파일러에 의해 구조체로 변환됩니다.

하나는 캡처가 없으므로 구성원이없고 인수가없는 생성자가 있습니다.

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

내 내기 컴파일러의 변환 따라서 IsSignificantBaselineField가 IsSignificantProjectField로 전환하고, 이에 IsSignificantProjectField은 두 공통 유형의 것을 의미 변환 생성자있어 그 생성자 explicit하지 않는다는 것이다. 따라서 전화는 다음과 같습니다.

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

순 효과는 두 가지가 동일한 것을 수행한다는 것입니다.

물론 이것은 컴파일러 버그입니다.

+0

화려한 - 잘 추론! 그것은 올바른 설명 일 수 있습니다. –