AddConstRef元函数异常行为疑问:为何代码可编译通过?
为什么这段C++代码能编译通过?
先看你给出的代码片段:
#include <type_traits> template<typename T> struct AddConstRef { using type = const T&; }; int main() { static_assert(std::is_same<int&, AddConstRef<int&>::type>::value); return 0; }
你预期AddConstRef<int&>::type等价于const int&,static_assert应该失败,但实际代码能编译通过,核心原因在于C++的引用折叠规则和引用的const限定特性:
- 当模板参数
T是int&时,const T并不是你想的const int&——引用本身无法被const修饰(引用一旦绑定对象就不能更改绑定关系,const对引用没有实际意义),编译器会直接忽略这个const,所以const T等价于int&。 - 接下来
const T&就变成了int& &,而C++规定引用的引用会被折叠成单个引用,最终结果就是int&。
所以AddConstRef<int&>::type的实际类型是int&,和std::is_same的第一个参数完全匹配,static_assert自然不会触发编译错误。
如果想要实现「给非引用类型添加const引用,引用类型转换为const引用」的预期效果,可以修改模板:
#include <type_traits> template<typename T> struct AddConstRef { using type = std::add_lvalue_reference_t<std::add_const_t<std::remove_reference_t<T>>>; }; int main() { // 此时 AddConstRef<int&>::type 是 const int&,static_assert会失败 static_assert(std::is_same<int&, AddConstRef<int&>::type>::value); return 0; }
这段代码先移除T的引用属性,添加const限定后再重新添加引用,就能得到你最初预期的const int&。
内容的提问来源于stack exchange,提问作者kindanoob
相关产品推荐
相关产品推荐

