Вызов 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’, IsSignificantProjectField вызывается с помощью std :: any_of, в то время как мое намерение состоит в том, чтобы в этом случае вызывался IsSignificantBaselineField.

Пожалуйста, кто-нибудь может объяснить ошибку в моей логике?

3

Решение

Итак, вот мое предположение, почему код компилируется и показывает поведение, которое вы наблюдаете.

Лямбды оба преобразуются в структуры компилятором.

Один не имеет захватов, и, следовательно, нет членов и конструктор без аргументов.

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

В итоге обе ветви делают одно и то же.

Это конечно ошибка компилятора.

9

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector