#c #lambda
#c #лямбда
Вопрос:
Я работаю над небольшим игровым заданием snake, используя только окно консоли, и я застрял в функции draw, где консоль должна быть очищена, а затем нарисовать сетку и другие компоненты (змея, хвост и фрукт)
и это код:
void draw()
{
system("cls");
for(int h = 0;h < HEIGHT;h )
{
for(int w = 0;w < WIDTH ; w )
{
if(h == snake.y amp;amp; w == snake.x)std::cout << snake.symbol;
else if( [amp;](){for(Snake::Tail T : snake.tails)
{if(T.x == w amp;amp; T.y == h)return true;}return false;}
== true)
{std::cout << snake.tailSymbol;}
else if(h == fruit.y amp;amp; w == fruit.x)std::cout << fruit.symbol;
else std::cout << "O";
}
std::cout << "n";
}
}
это может показаться запутанным, но что это делает, это перебирает каждую позицию в сетке и сначала проверяет, находится ли змея (голова змеи) в этой позиции,
в противном случае он проходит через цикл из всех хвостов, подключенных к змейке С ИСПОЛЬЗОВАНИЕМ ЛЯМБДА
остальное не важно, но проблема в том, что мне пришлось использовать лямбда-выражение, чтобы объединить оператор if и цикл for вместе, не нарушая цепочку «else», но проблема в том, что когда я пытаюсь проверить, возвращает ли лямбда-выражение true или false, я получаю сообщение об ошибке:
...Snakemain.cpp|40|error: no match for 'operator==' (operand types are 'draw()::<lambda()>' and 'bool')|
мой опыт работы с лямбда-выражением в c пока не настолько солиден, но я все еще хочу использовать лямбда-выражение, а не функцию, как я могу исправить ошибку и проверить значение?
Комментарии:
1. Не эксперт в C , но почему бы не определить функцию и не вызвать ее в вашей «цепочке if»? Это было бы намного проще для чтения и соответствовало бы той же цели.
2. 1) Нет особого смысла создавать, а затем напрямую вызывать лямбда-выражение, как показано; 2) Код завершается с ошибкой, учитывая лямбда-выражение like
auto l = []{ return true; };
при использовании asbool x = l == true;
, потому что он пытается сравнить лямбда-выражение с true (что по умолчанию запрещено) иbool x = l() == true;
которое вызывает лямбда-выражение и использует логический результат.3. @NoDataFound Я знаю, что это было бы проще, но я предпочитаю трудный путь ради обучения
Ответ №1:
Вы сравниваете лямбда-выражение с bool
, что недопустимо. Вам нужно вызвать лямбда-выражение и сравнить полученный результат, вот так:
else if ([amp;]() {
for (Snake::Tail T : snake.tails) {
if (T.x == w amp;amp; T.y == h)
return true;
}
return false;
}() // call it
== true)
Есть несколько упрощений, которые вы могли бы сделать. Для начала, сравнение с bool
с == true
является избыточным и не способствует удобочитаемости. for
Цикл может быть заменен алгоритмом, подобным этому:
else if ([amp;]() {
return std::any_of(snake_tails.begin(), snake_tails.end(),
[amp;](auto T) {
return T.x == w amp;amp; T.y == h;
});
}())
Поскольку теперь вы возвращаете только одно значение из лямбда-выражения, вы могли бы полностью отказаться от лямбда-выражения и просто использовать возвращаемое значение:
else if (std::any_of(snake_tails.begin(), snake_tails.end(),
[amp;](auto T) {
return T.x == w amp;amp; T.y == h;
}))
Комментарии:
1. это выглядит еще более странно, но если компилятор говорит, что это работает, то кто я такой, чтобы спорить, спасибо за помощь
2. Хуже того, лямбда-выражение без захвата может сравниваться с bool посредством преобразования в указатель на функцию. Но тело не будет вычислено, и результат всегда будет таким, как если бы лямбда-выражение было истинным.
3. Нет проблем. Это форматирование выглядит странно или тот факт, что вам нужно дополнительное
()
?4. это extra (), как я уже сказал, я не привык использовать lambda, поэтому способ структурирования всей лямбды выглядит для меня чуждым
5.
[](){}
Часть — это лямбда-выражение, которое представляет собой функцию, готовую к вызову. Final()
на самом деле вызывает его, jjust llikef()
бы.