为何a为true、b为false?foo1的T是const int,foo2返回类型仅为int?
为什么
foo1的模板参数推导为const int而foo2对应的decltype结果是int? 咱们一步一步拆解这个问题,先理清foo1的逻辑,再分析foo2里容易混淆的细节:
一、foo1中T推导为const int,所以a = true
先看foo1的模板定义:
template<typename T> constexpr bool foo1(T &) { return std::is_const<T>::value; }
当传入const int x这个实参时,C++的模板参数推导规则会这样工作:
- 函数参数是
T&类型,实参是带const限定的左值(const int类型的左值)。 - 对于引用类型的函数参数,推导模板参数
T时会完整保留实参的顶层const限定符。也就是说,为了让T&匹配实参的const int&类型,T必须被推导为const int。
所以std::is_const<T>::value等价于std::is_const<const int>::value,结果自然是true,因此constexpr bool a = foo1(x)的值为true。
二、foo2的返回类型是const int,但decltype(foo2(x))是int,所以b = false
再看foo2的模板定义:
template<typename T> T foo2(T &);
同样传入const int x时,模板参数T的推导逻辑和foo1完全一致:T被推导为const int,所以foo2的返回类型是const int。那为什么std::is_const<decltype(foo2(x))>::value是false呢?
问题出在decltype的特殊行为上:
foo2(x)是按值返回的函数调用,它的结果是一个纯右值(prvalue)。- 根据C++标准,
decltype作用于纯右值时,会忽略该类型的顶层const限定符。也就是说,虽然foo2的返回类型是const int,但decltype(foo2(x))最终得到的类型是int,而非const int。
所以std::is_const<int>::value就是false,因此constexpr bool b的值为false。
总结一下:
foo1的T推导保留了实参的const,因为参数是引用类型;foo2的T同样推导为const int,但返回值是纯右值,decltype会忽略其顶层const,导致最终判断为非const类型。
内容的提问来源于stack exchange,提问作者omicronns
相关产品推荐
相关产品推荐

