C++ 0x lambda返回值类型推理规则

Fer*_*cio 2 lambda type-inference c++11

考虑以下VC++ 10.0代码中的两个lambda函数:

template <typename T>
void eq(uint fieldno, T value) {
    table* index_table = db.get_index_table(fieldno);
    if (index_table == nullptr) return;
    std::set<uint> recs;
    index_table->scan_index<T>(value, [&](uint recno, T n)->bool {
        if (n != value) return false;
        recs.insert(recno);
        return true;
    });
    add_scalar_hits(fieldno, recs).is_hit =
        [=](tools::wsdb::field_instance_t& inst) {
            return boost::get<T>(inst) == value;
        };
}
Run Code Online (Sandbox Code Playgroud)

在第一个lambda函数中,我被迫使用->bool返回类型规范,而在第二个lambda中,编译器非常乐意推断返回类型.

我的问题是:编译器何时能推断出lambda的返回类型?只有当你有一个简单的单行时?

ken*_*ytm 5

"只有当你有一个简单的单行时才会这样吗?"

是.根据最新的公共C++ 0x草案(§5.1.2/ 4),

如果lambda表达式不包含trailing-return-type,则就好像trailing-return-type表示以下类型:

  • 如果复合语句是形式

    { return attribute-specifier opt 表达式 ; }

    lvalue-to-rvalue转换(4.1),数组到指针转换(4.2)和函数到指针转换(4.3)之后返回表达式的类型;

  • 否则,void.

[ 例如:

 auto x1 = [](int i){ return i; }; // OK: return type is int
 auto x2 = []{ return { 1, 2 }; }; // error: the return type is void (a
                                   // braced-init-list is not an expression)
Run Code Online (Sandbox Code Playgroud)

- 结束例子 ]

因此,您的第一个lambda表达式被解释为返回void,这是不对的,因此您需要添加一个-> bool以显式指定返回类型.