Lambda的显式返回类型

Rya*_*yan 74 c++ lambda visual-c++ c++11 visual-c++-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;
  });
}
Run Code Online (Sandbox Code Playgroud)

我是如何指定lambda具有'void'返回类型的.此外,如何指定lambda具有'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); }));
}
Run Code Online (Sandbox Code Playgroud)

Set*_*gie 165

您可以-> Type在参数列表后使用显式指定lambda的返回类型:

[]() -> Type { }
Run Code Online (Sandbox Code Playgroud)

但是,如果lambda有一个语句并且该语句是一个return语句(并且它返回一个表达式),则编译器可以从返回的表达式的类型中推导出返回类型.lambda中有多个语句,因此不会推断出类型.

  • -1:这不是编译器错误.标准非常明确:第5.1.2节第4段列出了如何进行扣除以及在何种条件下进行扣除. (9认同)
  • 编译器可以做到这一点,但标准禁止它这样做. (4认同)
  • @NicolBolas修复了. (2认同)
  • 尽管根据最新草案不允许这样做,但我发现最终补丁程序中的注释实际上似乎允许使用该补丁的注释,网址为http://gcc.gnu.org/ml/gcc-patches/2011-08 /msg01901.html。有人有最终规格要验证吗? (2认同)
  • 我已经广泛使用了lambda表达式,但没有一次明确声明返回类型。即使lambda表达式中有多个return语句,也可以完美地推论return类型(至少在VS2012和VS2013下)。当然,各种return语句需要在同一lambda表达式内匹配。例如,“ auto f = [](int i){if(i&gt; 5)返回true;返回false;};”这样的语句 编译没有问题,如果您调用“ auto b = f(10);”,b将为bool类型,当然是真实的; (2认同)
  • `return nullptr;` 可能会给类型推导带来麻烦,即使它与返回的任何指针类型一样有效。 (2认同)

Nic*_*las 13

可以推导出lambda的返回类型(在C++ 11中),但只有当只有一个语句时,该语句才是return返回表达式的语句(例如,初始化列表不是表达式).如果你有一个多语句lambda,那么假定返回类型是无效的.

因此,你应该这样做:

  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;
  })
Run Code Online (Sandbox Code Playgroud)

但实际上,你的第二个表达方式更具可读性.


Val*_*len 5

当仍然返回时,您可以有多个语句:

[]() -> your_type {return (
        your_statement,
        even_more_statement = just_add_comma,
        return_value);}
Run Code Online (Sandbox Code Playgroud)

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

  • 逗号是一个令人反感的运营商.它使那些不了解其存在或优先级的人感到困惑.imo永远不会有效使用.可以通过更多功能或更好的组织代码来避免它. (3认同)
  • 当然,你肯定给出了一个有效的答案,我只是不喜欢做任何鼓励甚至展示不良做法的事情。一旦人们了解到逗号是一个运算符,他们就会开始滥用它,直到他们学得更好为止,倒计时就会更长。:) (2认同)