1 template <typename T> 2 class TD; 3 4 int& foo(){ 5 static int x=0; 6 return x; 7 } 8 9 int main(){ 10 11 auto lambda = []()->const auto&{ return foo(); }; 12 TD<decltype(lambda())> dummy; 13 }
第11行,返回值類型按照const auto& 模式推導。這是用戶指定的方式,能夠隨意指定成auto先後能夠添加volatile const & && * **等修飾符,只要能推導成功就行。函數
固然,也能夠指定一個具體類型:spa
1 template <typename T> 2 class TD; 3 4 int& foo(){ 5 static int x=0; 6 return x; 7 } 8 9 int main(){ 10 11 auto lambda = []()->long{ return foo(); }; 12 TD<decltype(lambda())> dummy; 13 }
第11行,強制返回值類型爲long,只要foo()到long隱式轉換能ok。code
第三種是按返回值表達式,實現完美轉發。就是按照返回值表達式的實際類型,不失真的肯定函數的返回值。blog
template <typename T> class TD; int&& foo(){ return 10; } int main(){ auto lambda = []()->decltype(auto){ return foo(); }; TD<decltype(lambda())> dummy; }
這種方式須要decltype(auto)語法。
若是函數的返回值是void(函數體沒有return語句; 或者return f()且void f();)則如下等價:遞歸
auto lambda = []()->decltype(auto){ }; auto lambda = []()->auto{ }; auto lambda = [](){ };
可是下面的不行:編譯
auto lambda = []()->const auto{ };
對於函數中有多個出口return語句,要求各個return返回值表達式的類型必須相同。class
1 template <typename T> 2 class TD; 3 4 int foo(){ return 1;} 5 long bar(){ return 2;} 6 7 int main(){ 8 9 auto lambda = []() { 10 return bar(); 11 return foo(); 12 }; 13 TD<decltype(lambda())> dummy; 14 }
編譯失敗了,由於foo,bar返回值不一樣。推導返回值時遇到矛盾。除非具體指定一個返回值:lambda
template <typename T> class TD; int foo(){ return 1;} long bar(){ return 2;} int main(){ auto lambda = []()->int { return bar(); return foo(); }; TD<decltype(lambda())> dummy; }
若是是函數遞歸調用,要求函數體內第一個return語句表達式中不能有遞歸函數的存在。語法