C++ return type deduction
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 & && * **等修饰符,只要能推导成功就行。
当然,也可以指定一个具体类型:
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。
第三种是按返回值表达式,实现完美转发。就是按照返回值表达式的实际类型,不失真的确定函数的返回值。
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返回值表达式的类型必须相同。
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返回值不同。推导返回值时遇到矛盾。除非具体指定一个返回值:
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语句表达式中不能有递归函数的存在。