std::is_same_v处理const指针返回false的异常问题问询
解决const指针场景下std::is_same_v返回false的问题
你的问题出在类型转换顺序错误,以及对std::remove_cv_t的作用范围理解有误:
问题根源
std::remove_cv_t只会移除类型的顶级const/volatile限定符,对于const char*(等价于char const*)来说,const是修饰指针指向的内容(底层const),而非指针本身的顶级限定符。所以原代码中:
- 对
const char*调用std::decay_t后结果仍是const char* - 接着调用
std::remove_cv_t,因为没有顶级cv限定符,返回的还是const char* - 最后
std::remove_pointer_t得到的是const char,和char自然不相等,导致std::is_same_v返回false
而你看到typeid输出的类型名称相同,是因为编译器的typeid(T).name()实现通常会忽略底层cv限定符,实际类型是const char,和char是不同的类型。
修正后的代码
调整类型转换顺序,先移除指针得到指向的类型,再移除该类型的cv限定符:
#include <type_traits> template<typename T> constexpr bool checkType() { // 先拆指针,再移除指向类型的cv限定 return std::is_same_v<std::remove_cv_t<std::remove_pointer_t<std::decay_t<T>>>, char>; } int main() { static_assert(checkType<char*>(), "char* should be true"); static_assert(checkType<const char*>(), "const char* should be true"); return 0; }
验证测试代码
把你的测试代码中的cx定义修改为正确的顺序,就能得到预期结果:
#include <type_traits> #include <iostream> template<typename T> void do_() { #define cx std::remove_cv_t<std::remove_pointer_t<std::decay_t<T>>> std::cout << "T: " << typeid(T).name() << " (" << typeid(T).raw_name() << "), " << "Tred: " << typeid(cx).name() << " (" << typeid(cx).raw_name() << "), \n" << "icb?: " << (std::is_same_v<cx, char> ? "true" : "false") << ", " << "iib?: " << (std::is_same_v<cx, int> ? "true" : "false") << "\n"; } int main() { do_<char>(); do_<char*>(); do_<const char*>(); do_<int>(); do_<int*>(); do_<const int*>(); return 0; }
运行后const char*对应的icb?会输出true,符合预期。
内容的提问来源于stack exchange,提问作者edc
相关产品推荐
相关产品推荐

