一句话,lambda返回类型自动推导走的是auto,而不是decltype,注意。
class ObjectA { public: ObjectA() { val_ = ++g; } ObjectA(const ObjectA& other) { val_ = ++g; } ~ObjectA() { val_ = 0; } ObjectA& operator=(const ObjectA& other) { if (this != &other) { val_ = ++g; } return *this; } int val_; }; const ObjectA& funcPlaceholder() { return ObjectA(); } class Test { public: ObjectA& returnValue() { return val_; } const ObjectA& returnConstValue() const { return val_; } ObjectA val_; }; void useRetValRef(std::function<ObjectA&()> func) { ObjectA& v = func(); } void useRetValConstRef(std::function<const ObjectA&()> func) { const ObjectA& v = func(); const ObjectA& v2 = funcPlaceholder(); } int main(int argc, wchar_t* argv[]) { Test tt; // 下面的lambda使用了自动返回类型推导->ObjectA,而不是ObjectA&,所以编译器报错,函数类型不匹配 // f的类型是ObjectA(),而使用f的要求是ObjectA&() // auto f = [&tt](){return tt.returnValue();}; // useRetValRef(f); // 下面这个情况也类似,j是ObjectA类型而不是ObjectA& auto j = tt.returnValue(); j.val_ = 10; // 这样i就是ObjectA&了,decltype是编译时推导,不会产生任何运行时代码 decltype(tt.returnValue()) i = tt.returnValue(); i.val_ = 10; tt.val_.val_ = 20; // 下面会引起warning C4172: returning address of local variable or temporary, // 因为lambda使用了自动返回类型推导->ObjectA,函数返回值,而不是引用 // 而使用f2的地方用const&接收了这个值,所以模版展开后出现类似这样的代码 /* const ObjectA& func() { return ObjectA(); } */ auto f2 = [&tt]() { return tt.returnConstValue(); }; useRetValConstRef(f2); return 0; }