decltype 说明符[c++11]
在我们编写函数模板的时候可能会遇到很多的问题
1 2 3 4 5 6 7 | template < typename T1, typename T2> void function(T1 x, T2 y) { ... ? type ? result = x + y; ... } |
上面的例子中,我们可以发现一个很明显的问题——有时候在函数模板中我们并不知道某个表达式产生的结果具体是什么类型。
decltype关键字[c++11]
c++11新增的关键字decltype可以用于解决上述问题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #include <iostream> using namespace std; template < typename T1, typename T2> void function(T1 x, T2 y) { decltype (x + y) result = x + y; cout << result << endl; } int main() { function(10, 20); function(10, 52.1); } |
decltype关键字用于查询表达式的数据类型,为确定类型编译器必须遍历一个核对表
假设有如下声明:
1 | decltype (expression) var; |
- 第一步,如果expression是一个没有用括号括起的标识符,则var的类型和标识符的类型相同,包括const等限定符。
-
1234567
double
x = 1.1;
double
& rx = x;
const
double
* pd;
decltype
(x) a;
//a is type double
decltype
(rx) b = x;
//b is type double &
decltype
(pd) c;
//c is type const double *
-
- 第二步,如果expression是一个函数调用,则var的类型与函数的返回值类型相同(不会调用函数)。
-
1
decltype
(function(2)) num;
//不会调用函数
-
- 第三步,如果expression是一个用括号括起来的左值,则var为指向其类型的引用。
-
12345
int
num1 = 95;
decltype
(num1) x = 100;
//x is type int
decltype
((num1)) y = num1;
// y is type int &
-
- 第四步,如果前面的条件都不满足,则var的类型和expression的类型相同。
-
12345678
int
a = 10;
int
b = 20;
int
& ra = a;
int
& rb = b;
decltype
(100L) num1 = 100;
//num1 is type long
decltype
(a * b) num2 = 100;
//num2 is type int
decltype
(ra + rb) num3 = 10;
//num3 is type int
-
注意:和sizeof一样decltype不需要对操作数求值
decltype的常见用法
- 结合typedef使用
- 后置返回类型
1)需要多次声明的时候可以结合typedef使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #include <iostream> using namespace std; template < typename T1, typename T2> void function(T1 x, T2 y) { typedef decltype (x + y) xy_type; xy_type num1 = x + y; xy_type num2 = x * y; xy_type num3 = x / y; cout << "x + y: " << num1 << endl; cout << "x * y: " << num2 << endl; cout << "x / y: " << num3 << endl; } int main() { function(10, 20); } |
2)c++11后置返回类型
文章开头的例子中我们不难发现另一个的问题——在创建函数模板的时候我们并不能够确定返回值的具体类型。那么我们能够利用类似于decltype(x + y)来确定函数的返回值类型吗?
答案是:不能,因为此时还未声明参数x、y。针对此问题c++11中给出了解决方案——后置返回类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | #include <iostream> using namespace std; template < typename T1, typename T2> auto function(T1 x, T2 y)-> decltype (x + y) { return x + y; } int main() { cout << function(10, 20) << endl; } |
注意此行:
1 | auto function(T1 x, T2 y)-> decltype (x + y) |
在这里->decltype(x + y)被称为后置返回类型,auto代表一个占位符表示后置返回类型提供的类型
这种语法也可以用于函数定义,例如一个函数需要返回数组指针时
1 | auto func( int i) -> int (*)[10]; //返回一个指向包含10个int元素的指针 |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」