std::is_const仅检测类型顶层const限定,对const int*等底层const无效;需配合remove_pointer_t/remove_reference_t剥离后判断,且不响应volatile、constexpr及模板推导中的类型折叠。

std::is_const 用来判断类型是否带 const 限定,但只看顶层 cv 限定
它不关心 int const* 这种“指针所指是 const”的情况,只认 int const 或 int const& 这类顶层加了 const 的类型。常见误用就是拿它去测指针或引用的底层 const 性,结果永远返回 false。
-
std::is_const_v<const int></const>→true -
std::is_const_v<int const></int>→false(指针本身非常量) -
std::is_const_v<const int></const>→true(引用类型顶层是 const) -
std::is_const_v<int></int>→false(非常量引用)
想判断“指向 const 的指针”得先去掉引用和指针
要检测 const int* 中的 const,必须先剥离掉指针层级,再对指向类型做判断。直接对原类型用 std::is_const 没用,得组合 std::remove_pointer_t 和 std::remove_reference_t。
- 对
const int*:用std::is_const_v<:remove_pointer_t int>></:remove_pointer_t>→true - 对
int const*:同上,std::remove_pointer_t得到const int,再判 const 成立 - 嵌套多层指针如
int**,需多次std::remove_pointer_t,不能一步到位
std::is_const 对 volatile 无效,也不能区分 const 和 constexpr
std::is_const 只响应 const 修饰符,对 volatile、constexpr、consteval 都无反应。它也不管变量是不是字面量、有没有初始化——只看类型声明里有没有顶层 const。
-
std::is_const_v<const volatile int></const>→true(含 const 就真) -
std::is_const_v<volatile int></volatile>→false -
constexpr int x = 42;,decltype(x)是int,不是const int,所以std::is_const_v<decltype></decltype>→false
模板推导中容易忽略 const 引用的类型折叠
写模板函数时,如果参数是 T&&,传入 const int&,T 会被推成 const int&,而非 const int。此时 std::is_const_v<t></t> 是 false(因为 const int& 的顶层是引用,不是 const),但 std::is_const_v<:remove_reference_t>></:remove_reference_t> 才是 true。
立即学习“C++免费学习笔记(深入)”;
- 别在模板里直接对
T用std::is_const,先考虑是否要std::remove_reference_t或std::decay_t -
std::decay_t<t></t>会去掉引用、cv 限定,并把数组/函数转指针,适合通用场景,但会丢失原始 const 信息 - 真正要保留 const 判断逻辑时,明确决定剥离哪一层——引用?指针?还是两者都要?
std::is_const 的返回值几乎总是在提醒你:它看到的,只是你写的那一行声明里最外头那个 const。










