Лямбда-выражение для возврата bool в операторе if - PullRequest
4 голосов
/ 24 мая 2019

Просто чтобы перейти к сути, я хочу вернуть true или false, используя лямбда-выражение внутри оператора if(). Я видел этот вопрос, который похож на мой: ССЫЛКА , но я не смог найти ответ.

Так вот мой пример кода:

if([&rel_pose](Eigen::VectorXd pose)
    {
        return (sqrt(pose(0) * pose(0) + pose(1) * pose(1)) < 2) ? true : false;
    }) // do smth

Когда я пытаюсь скомпилировать, я получаю эту ошибку:

 error: could not convert ‘<lambda closure object>graphslam::GraphSLAM::main_pose_callback(const ConstPtr&)::<lambda(Eigen::VectorXd)>{rel_pose}’ from ‘graphslam::GraphSLAM::main_pose_callback(const ConstPtr&)::<lambda(Eigen::VectorXd)>’ to ‘bool’
  })

Хорошо, читая ошибку, я подумал, что не вызывал функцию, поскольку компилятор не рассматривает выражение как bool. Поэтому я попытался использовать этот код:

if(([&rel_pose](Eigen::VectorXd pose)
    {
        return (sqrt(pose(0) * pose(0) + pose(1) * pose(1)) < 2) ? true : false;
    };)) // do smth

И ошибка:

expected ‘)’ before ‘;’ token
  };)) return;

Это может показаться очевидной ошибкой, но для меня я, вероятно, неправильно понимаю синтаксис и подумал спросить, что происходит.

EDIT: Обратите внимание, что я упростил код, чтобы вы могли легко воспроизвести ошибку. Я знаю, что лямбда-выражения в данном конкретном случае не имеют никакого смысла.

Ответы [ 3 ]

7 голосов
/ 24 мая 2019

ты забыл назвать свою лямбду.Прямо сейчас вы говорите if(function_pointer), следовательно, компилятору не удалось преобразовать это в логическое выражение.


Простое предложение if с логической лямбдой, следовательно, записывается как:

if ([]() {
    return true;
}()) {
    //do sth
}

У вас также есть ошибка, когда переменная является параметром при ее одновременной записи.Вы должны решить, так что либо:

if([](Eigen::VectorXd pose)
    {
        return (sqrt(pose(0) * pose(0) + pose(1) * pose(1)) < 2) ? true : false;
    }(rel_pose)){
    //do sth
}

или

if([&rel_pose]()
    {
        return (sqrt(rel_pose(0) * rel_pose(0) + rel_pose(1) * rel_pose(1)) < 2) ? true : false;
    }()){
    //do sth
}

Необходимость лямбды в этом случае сомнительна, вы можете просто избавиться от лямбды, оставивлогическое выражение в предложении if.Если говорить об этом - не нужно здесь использовать троичный оператор.return sqrt(rel_pose(0) * rel_pose(0) + rel_pose(1) * rel_pose(1)) < 2; достаточно и более читабельно.

3 голосов
/ 24 мая 2019

это определение лямбда-выражения с захватом, а не лямбда

[&rel_pose](Eigen::VectorXd pose)
{
  return (sqrt(pose(0) * pose(0) + pose(1) * pose(1)) < 2) ? true : false;
}

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

[](Eigen::VectorXd pose)
{
  return (sqrt(pose(0) * pose(0) + pose(1) * pose(1)) < 2) ? true : false;
}(rel_pose)

Я думаю, что это правильно

3 голосов
/ 24 мая 2019

Лямбда - это функциональный объект. Вы должны вызвать его с помощью ().

if ([](Eigen::VectorXd pose)
    {
        return (sqrt(pose(0) * pose(0) + pose(1) * pose(1)) < 2) ? true : false;
    }(rel_pose)) { /* ... */ }

Вы передаете rel_pose в качестве аргумента вместо его захвата. В любом случае, вы должны сделать ссылку pose const

Тем не менее, я не знаю, что вы пытаетесь сделать здесь. Это было бы лучше:

if (sqrt(foo(0) * foo(0) + foo(1) * foo(1)) < 2) { /* ... */ }
...