Явный тип возврата лямбда - PullRequest
69 голосов
/ 08 марта 2012

Когда я пытаюсь скомпилировать этот код (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'?

UPDATE

Следующие компиляции. Может кто-нибудь сказать мне, почему это компилируется, а другой нет?

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

Ответы [ 3 ]

159 голосов
/ 08 марта 2012

Вы можете явно указать тип возврата лямбды, используя -> Type после списка аргументов:

[]() -> Type { }

Однако, если лямбда имеет один оператор и этот оператор является оператором возврата (и этовозвращает выражение), компилятор может определить тип возвращаемого значения из типа этого возвращаемого выражения.У вас есть несколько операторов в вашей лямбде, поэтому она не выводит тип.

11 голосов
/ 08 марта 2012

Тип возврата лямбды (в 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;
  })

Но на самом деле ваше второе выражение очень многоболее читабельно.

5 голосов
/ 27 сентября 2014

Вы можете иметь более одного оператора, когда все еще возвращаете:

[]() -> your_type {return (
        your_statement,
        even_more_statement = just_add_comma,
        return_value);}

http://www.cplusplus.com/doc/tutorial/operators/#comma

...