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语句表达式中不能有递归函数的存在。

posted @ 2018-04-06 09:36  thomas76  阅读(566)  评论(0编辑  收藏  举报