在泛型编程中,可能需要通过参数的运算来得到返回值的类型。考虑下面这个场景:

template <typename R, typename T, typename U>R add(T t, U u){    return t+u;}int a = 1; float b = 2.0;auto c = add<decltype(a + b)>(a, b);

我们并不关心 a+b 的类型是什么,因此,只需要通过 decltype(a+b) 直接得到返回值类型即可。但是像上面这样使用十分不方便,因为外部其实并不知道参数之间应该如何运算,只有 add 函数才知道返回值应当如何推导。

那么,在 add 函数的定义上能不能直接通过 decltype 拿到返回值呢?

template <typename T, typename U>decltype(t + u) add(T t, U u)  // error: t、u尚未定义{    return t + u;}

当然,直接像上面这样写是编译不过的。因为 t、u 在参数列表中,而 C++ 的返回值是前置语法,在返回值定义的时候参数变量还不存在。

可行的写法如下:

template <typename T, typename U>decltype(T() + U()) add(T t, U u){    return t + u;}

考虑到 T、U 可能是没有无参构造函数的类,正确的写法应该是这样:

template <typename T, typename U>decltype((*(T*)0) + (*(U*)0)) add(T t, U u){    return t + u;}

虽然成功地使用 decltype 完成了返回值的推导,但写法过于晦涩,会大大增加 decltype 在返回值类型推导上的使用难度并降低代码的可读性。

因此,在 C++11 中增加了返回类型后置(trailing-return-type,又称跟踪返回类型)语法,将 decltype 和 auto 结合起来完成返回值类型的推导。返回类型后置语法是通过 auto 和 decltype 结合起来使用的。上面的 add 函数,使用新的语法可以写成:

template <typename T, typename U>auto add(T t, U u) -> decltype(t + u){    return t + u;}

为了进一步说明这个语法,再看另一个例子:

int& foo(int& i);float foo(float& f);template auto func(T& val) -> decltype(foo(val)){    return foo(val);}

如果说前一个例子中的 add 使用 C++98/03 的返回值写法还勉强可以完成,那么这个例子对于 C++ 而言就是不可能完成的任务了。

在这个例子中,使用 decltype 结合返回值后置语法很容易推导出了 foo(val) 可能出现的返回值类型,并将其用到了 func 上。返回值类型后置语法,是为了解决函数返回值类型依赖于参数而导致难以确定返回值类型的问题。有了这种语法以后,对返回值类型的推导就可以用清晰的方式(直接通过参数做运算)描述出来,而不需要像 C++98/03 那样使用晦涩难懂的写法。

返回值类型与函数类型不匹配_C++返回值类型后置(跟踪返回值类型)相关推荐

  1. 若a为int类型,且其值为3,则执行完表达式a+= a-= a*a后,a的值是

    若a为int类型,且其值为3,则执行完表达式a+= a-= a*a后,a的值是 #include<stdio.h> int main() {int a=3; a+=a-=a*a;print ...

  2. Spring(十八):Spring AOP(二):通知(前置、后置、返回、异常、环绕)

    AspectJ支持5种类型的通知注解: @Before:前置通知,在方法执行之前执行: @After:后置通知,在方法执行之后执行: @AfterRunning:返回通知,在方法返回结果之后执行(因此 ...

  3. SQL函数类型及函数使用大全

    转载地址:http://www.cnblogs.com/moss_tan_jun/archive/2010/08/23/1806861.html 一旦成功地从表中检索出数据,就需要进一步操纵这些数据, ...

  4. c++中运算符重载(加号运算,左移运算,前置后置++运算符,赋值运算,关系运算,函数运算)

    运算符重载注意 重载的运算符要易读 内置的数据类型的表达式的运算符是不可以改变的 不要重载&& 和 | | 运算符 =,[]和->运算符只能通过成员函数进行重载 << ...

  5. printf函数输出多个printf 、前置加加或者后置加加

    目录 (1)前置加加和后置加加的区别 (2)printf输出前置加加 (3)printf输出后置加加 (4)printf输出printf (1)前置加加和后置加加的区别 首先我们先来了解一下前置加加和 ...

  6. 函数前置条件和后置条件

    前置条件指调用者调用该函数之前必须满足的条件.一般来说,前后置条件都可以转化为assert语句. 比如传递个strcpy的参数必须都是有效指针,win32下调用socket之前,必须先调用WAStar ...

  7. 设置hash后导致的返回问题的解决方案

    设置hash后导致的返回问题的解决方案 参考文章: (1)设置hash后导致的返回问题的解决方案 (2)https://www.cnblogs.com/calvinjs/p/4928660.html ...

  8. import_array()报错,返回值类型与函数类型不匹配

    问题: C++调用python程序,导入python数组时import_array()出现返回值类型与函数类型不匹配. 解决办法: 首先环境必须要配置无误,保证有numpy包.如图,右键进入__mul ...

  9. php 函数返回值mixed,认识函数的类型、参数与返回值

    函数的类型.参数与返回值 一.函数的基本语法语法 functionfunctionName(类型限定参数列表):返回值类型 { } 案例:计算两个数之和. functionsum(int$a,int$ ...

最新文章

  1. 2022-2028年中国相变蜡行业市场前瞻与投资战略规划分析报告
  2. ASP.NET中常用功能代码总结(5)——文件操作篇
  3. Python之单元测试
  4. 实现DIV居中布局三种途径(转)
  5. 小程序如何吸粉以及引流
  6. php yaf框架和icon,php中Yaf框架是什么?
  7. debian9.4网络配置及永久静态默认路由
  8. 周志华-机器学习西瓜书-第三章习题3.3 编程实现对率回归
  9. 力扣——罗马数字转整数
  10. 异步日志方案log4cpp
  11. Golang map 并发读写问题源码分析
  12. docker gitlab 初始密码查看
  13. 数字调制解调技术:第7章-COSATAS环载波频率参数设计问题
  14. 好文:中国Saas蜕变史
  15. 创建虚拟机步骤以及开启电脑虚拟设置方法
  16. 小米手机 怪诞行为经济学
  17. icloud安装错误怎么办_给你细说win7系统icloud win7安装失败的修复办法
  18. 该项目不在XXX中。请确认该项目的位置,然后重试。之解决办法
  19. win102004优化_这就是win102004版的17个新功能,微软windows真是越来越强了
  20. c语言生日快乐爱心,C语言 生日快乐

热门文章

  1. Memcached - In Action
  2. jmeter之调度器配置
  3. 读取网络数据缓存在本地 流程图
  4. 巧用组策略技术禁用办公室QQ聊天
  5. zoj-3802-Easy 2048 Again
  6. Unsupported major.minor version 51.0解决办法
  7. hdu 1203 I NEED A OFFER!
  8. 定义一个接口CanFly,描述会飞的方法public void fly();
  9. .Net Core 在 Linux-Centos上的部署实战教程(二)
  10. 新闻文字上下滚动代码