提问人:edc 提问时间:11/11/2023 更新时间:11/11/2023 访问量:69
std::is_same_v 的意外行为
Unexpected behavior with std::is_same_v
问:
我正在编写一个函数来检查指针指向的类型,但是当您使指针 const 时,std::is_same_v 返回 false。
下面是一个最小的可重现的例子,说明应该做什么:
#include <type_traits>
template<typename T>
constexpr bool checkType() {
return std::is_same_v<std::remove_pointer_t<std::remove_cv_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;
}
我试过更改 to 的顺序,甚至完全摆脱,但它仍然不起作用。我还尝试使用以下代码检查返回的类型:std::remove_cv_t<std::decay_t<T>>
std::decay_t<std::remove_cv_t<T>>
std::decay_t
std::remove_pointer_t
#include <type_traits>
#include <iostream>
template<typename T>
void do_() {
#define cx std::remove_pointer_t<std::remove_cv_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;
}
它返回以下内容:
T: char (.D), Tred: char (.D),
icb?: true, iib?: false
T: char * __ptr64 (.PEAD), Tred: char (.D),
icb?: true, iib?: false
T: char const * __ptr64 (.PEBD), Tred: char (.D),
icb?: false, iib?: false
T: int (.H), Tred: int (.H),
icb?: false, iib?: true
T: int * __ptr64 (.PEAH), Tred: int (.H),
icb?: false, iib?: true
T: int const * __ptr64 (.PEBH), Tred: int (.H),
icb?: false, iib?: false
这对我来说没有任何意义,因为类型的名称是相同的......但不是同一种类型吗? 我正在使用 Clang 17.0.4 (C++23),但我也在 MSVC (C++20) 中对其进行了测试,并且发生了相同的行为。
答:
4赞
Ninja
11/11/2023
#1
如果你的目标是检查 T 是否是指向 char(或 const char)的指针,则需要调整类型特征的使用。在与 char 进行比较之前,您希望删除指针而不是 const 限定符。
下面是 checkType 函数的修订版本,它应该适用于 char* 和 const char*:
#include <type_traits>
template<typename T>
constexpr bool checkType() {
using DecayedType = std::remove_pointer_t<T>; // Only remove pointer, keep const if present
return std::is_same_v<DecayedType, char> || std::is_same_v<DecayedType, const char>;
}
int main() {
static_assert(checkType<char*>(), "char* should be true");
static_assert(checkType<const char*>(), "const char* should be true");
return 0;
}
此修订版本通过将衰减类型(不带指针)与 char 和 const char 进行比较,正确地处理了 char* 和 const char*。
评论
1赞
Ted Lyngmo
11/11/2023
虽然意志有效,但在比较之前删除会使意图更清晰(i.m.o.):||
const
return std::is_same_v<std::remove_const_t<DecayedType>, char>;
上一个:更改大小磁贴 SCSS
下一个:CRTP 的部分模板专用化问题
评论
const char*
是“指向 const char 的(non-con-st) 指针”。 对它没有影响,因为它不是常量,也不是引用。 没有效果,因为它不是常量。 将其转换为“const char”。decay_t
remove_cv_t
remove_pointer_t
typeid
忽略顶级的一致性和参考性。这里有一种没有的方法:stackoverflow.com/a/59522794/2752075