Search code examples
c++gccc++17decltypetrailing-return-type

Inconsistency with lambda trailing return types


Consider this code with gcc-7.0.0 latest snapshot:

auto lambda1 = [](auto&& id) -> decltype(id == 10) { return id == 10; };
auto lambda2 = [](auto&& id) -> decltype(auto)     { return id == 10; };

static_assert(!std::experimental::is_detected_v<ResultOfT,decltype(lambda1),std::string>);
//static_assert(!std::experimental::is_detected_v<ResultOfT,decltype(lambda2),std::string>);
// This doesn't even compile!?
auto bb = std::experimental::is_detected_v<ResultOfT,decltype(lambda2),std::string>;

where ResultOfT is just a wrapper over std::result_of.

Why lambda1 and lambda2 are not equivalent in this sense?

Per my understanding decltype(auto) at lambda2 should be just the short form of decltype(id == 10), but in fact it isn't, so what is the reason?

Is this a bug in GCC?


Solution

  • The standard says:

    Function templates can use return type deduction. The deduction takes place at instantiation even if the expression in the return statement is not dependent. This instantiation is not in an immediate context for the purposes of SFINAE.

    So there is no bug in GCC, it follows the standard and lambda1 is NOT equivalent to lambda2.