问题
Consider this example:
#include <algorithm>
#include <iostream>
int main()
{
std::string str = "abcde4fghijk4l5mnopqrs6t8uvwxyz";
std::string str2;
std::remove_copy_if(str.begin(), str.end(),
std::back_inserter(str2),
[](char& c) {
if (std::isdigit(c))
return true; // <----- warning here
else
return false;
}
);
std::cout << str2 << '\n';
}
With GCC 4.6.1, this compiles fine and prints expected output (the alphabet) but I get a warning saying "lambda return type can only be deduced when the return statement is the only statement in the function body".
Now, I know how to get rid of the warning (using trailing return type or simply saying return isdigit(c);
), but I'm curious, since compiler doesn't warn for nothing (or so it should be): what could possibly go wrong in code like this? Does standard say anything about it?
回答1:
As @ildjarn says in his comment, your code is simply ill-formed according to the standard.
§5.1.2 [expr.prim.lambda] p4
[...] If a lambda-expression does not include a trailing-return-type, it is as if the trailing-return-type denotes the following type:
- if the compound-statement is of the form
{
attribute-specifier-seqoptreturn
expression ;}
the type of the returned expression after lvalue-to-rvalue conversion (4.1), array-to-pointer conversion (4.2), and function-to-pointer conversion (4.3);- otherwise,
void
.[...]
That's it, basically if the code inside the curly brackets (called compund-statement in the standard) is anything but return some_expr;
, the standard says the return type is undeducible and you get a void
return type.
回答2:
It is worth noting that this issue has been rectified in C++14. The language now correctly deduces the return type as the OP expected. From the draft standard [7.1.6.4.11]:
If the type of an entity with an undeduced placeholder type is needed to determine the type of an expression, the program is ill-formed. Once a return statement has been seen in a function, however, the return type deduced from that statement can be used in the rest of the function, including in other return statements. [ Example:
auto n = n; // error, n’s type is unknown auto f(); void g() { &f; } // error, f’s return type is unknown auto sum(int i) { if (i == 1) return i; // sum’s return type is int else return sum(i-1)+i; // OK, sum’s return type has been deduced }
—end example ]
来源:https://stackoverflow.com/questions/8582610/compiler-warning-lambda-return-type-cannot-be-deduced