当ParamType既非指针也非引用时auto类型推导的疑问
理解
const auto的类型推导:指针的顶层const vs 底层const 你遇到的问题核心是混淆了顶层const(修饰指针本身)和底层const(修饰指针指向的内容)在类型推导中的表现,以及auto与模板推导的对应逻辑。我们一步步拆解清楚:
你的代码推导过程
先看你给出的代码:
auto i = 2; // i的类型是int const auto c = &i; // &i是int*类型,auto推导为int* *c = 4; // 编译通过,运行后i的值变为4 std::cout << "i is " << i;
这里的const auto c,auto会被推导为int*(因为初始化表达式是&i,即int*类型),所以const auto等价于int* const——这是一个指向int的const指针:指针本身存储的地址不能被修改,但指针指向的内容(也就是i的值)是可以修改的,这就是为什么*c =4能正常运行并改变i的值。
你对模板推导的误解
你以为这段代码对应template<typename T> void f(const T param)的推导逻辑,但这里的关键是:当实参是int*时,模板推导会把T推导为int*,而不是你误以为的int。
我们模拟模板推导的过程:
template<typename T> void f(const T param); int main() { int i =2; f(&i); // 实参是int*类型 }
此时模板推导会将T匹配为int*,所以param的类型是const T = int* const——和你代码中c的类型完全一致!
如果你期望的是param的类型是const int*(指向const int的指针,即底层const),那对应的模板应该是:
template<typename T> void f(const T* param); // 此时T推导为int,param是const int*
对应的auto声明应该写成const auto* c = &i;,这时候auto推导为int,c的类型是const int*,此时*c =4会触发编译错误,因为指向的内容被const修饰,不可修改。
总结
const auto c = &i;→c是int* const(顶层const:指针本身不可变,指向内容可变)const auto* c = &i;→c是const int*(底层const:指向内容不可变,指针本身可变)- 模板推导中,
const T的const始终修饰T的顶层类型:如果T是指针,那就是指针本身const;如果T是基本类型,那就是值本身const。
内容的提问来源于stack exchange,提问作者sanjivgupta
相关产品推荐
相关产品推荐

