Когда я пытаюсь скомпилировать этот код (VS2010), я получаю следующую ошибку:
error C3499: a lambda that has been specified to have a void return type cannot return a value
void DataFile::removeComments()
{
string::const_iterator start, end;
boost::regex expression("^\\s?#");
boost::match_results<std::string::const_iterator> what;
boost::match_flag_type flags = boost::match_default;
// Look for lines that either start with a hash (#)
// or have nothing but white-space preceeding the hash symbol
remove_if(rawLines.begin(), rawLines.end(), [&expression, &start, &end, &what, &flags](const string& line)
{
start = line.begin();
end = line.end();
bool temp = boost::regex_search(start, end, what, expression, flags);
return temp;
});
}
Как я указал, что лямбда имеет возвращаемый тип void. Более того, как мне указать, что лямбда имеет возвращаемый тип bool?
ОБНОВИТЬ
Следующие компиляции. Может кто-нибудь сказать мне, почему он компилируется, а другой нет?
void DataFile::removeComments()
{
boost::regex expression("^(\\s+)?#");
boost::match_results<std::string::const_iterator> what;
boost::match_flag_type flags = boost::match_default;
// Look for lines that either start with a hash (#)
// or have nothing but white-space preceeding the hash symbol
rawLines.erase(remove_if(rawLines.begin(), rawLines.end(), [&expression, &what, &flags](const string& line)
{ return boost::regex_search(line.begin(), line.end(), what, expression, flags); }));
}
->
, например[&](double d) -> double { //...
[&]...
), поскольку то, что у вас есть в настоящее время, излишне многословно.[&expression, &start, &end, &what, &flags]...
(твое) против[&]...
(мое). А теперь скажите, чей из них более подробный. ;)[&]
указывает лямбда-выражению захватывать все, что вы используете внутри тела лямбда-выражения, по ссылке. Это называется «захват по умолчанию». Другой -[=]
и будет копировать.Ответы:
Вы можете явно указать возвращаемый тип лямбды, используя
-> Type
после списка аргументов:Однако, если лямбда-выражение имеет один оператор, и этот оператор является оператором возврата (и возвращает выражение), компилятор может вывести тип возвращаемого значения из типа этого одного возвращенного выражения. У вас есть несколько операторов в лямбде, поэтому он не определяет тип.
источник
return nullptr;
может бросить вызов при выводе типа, даже если он действителен, как и любой другой тип указателя, возвращаемый в противном случае.Тип возвращаемого лямбда- выражения (в C ++ 11) можно вывести, но только если есть ровно один оператор, и этот оператор является
return
оператором, возвращающим выражение (например, список инициализаторов не является выражением). Если у вас есть лямбда с несколькими операторами, то предполагается, что возвращаемый тип недействителен.Следовательно, вам следует сделать следующее:
remove_if(rawLines.begin(), rawLines.end(), [&expression, &start, &end, &what, &flags](const string& line) -> bool { start = line.begin(); end = line.end(); bool temp = boost::regex_search(start, end, what, expression, flags); return temp; })
Но на самом деле ваше второе выражение намного читабельнее.
источник
);
в конце?Когда вы все еще возвращаетесь, у вас может быть более одного оператора:
[]() -> your_type {return ( your_statement, even_more_statement = just_add_comma, return_value);}
http://www.cplusplus.com/doc/tutorial/operators/#comma
источник