为何decltype(ConstInt{})的推导结果不是const类型?
为何decltype(ConstInt{})的推导结果不是const类型?
这个问题其实是C++类型系统里一个容易踩坑的小细节,咱们一步一步拆解来看就懂了。
先看你代码里的对比现象:
- 对于
ConstStr(也就是const std::string),decltype(ConstStr{})确实推导为const std::string,完全符合预期; - 但
ConstInt是const int,decltype(ConstInt{})却变成了int,这就很让人摸不着头脑。
背后的原因其实是C++标准里的一条特殊规则:
当你创建一个非类、非数组类型的const限定纯右值(简单说就是临时值)时,这个const限定会被编译器自动忽略。
为啥要这么设计?因为基本类型(比如int、float这类)的临时值本身就是不可修改的——你总不能写int{} = 10;这种代码吧?所以给基本类型的临时值加const完全是冗余的,编译器干脆直接把这个const属性丢掉了。
而类类型(比如std::string)就不一样了:const std::string的临时对象是有实际意义的——它只能调用类的const成员函数,不能调用非const的,所以这个const限定会被完整保留下来,不会被编译器忽略。
对应到你的代码里:
ConstInt{}本质是const int{},属于非类类型的const临时值,编译器自动忽略const,所以这个表达式的类型是int;而decltype对纯右值表达式的推导规则就是直接取表达式的类型,所以最终得到int;ConstStr{}是const std::string{},属于类类型的const临时值,const被保留,表达式类型是const std::string,所以decltype推导结果也符合预期。
如果你还是有点懵,可以试试这个小实验:给const int{}加个括号变成(ConstInt{}),再用decltype推导——不过这个涉及到decltype对带括号表达式的特殊规则,这里就不展开了,核心还是刚才说的类与非类类型的const临时值处理差异。
内容来源于stack exchange
相关产品推荐
相关产品推荐

