std::is_signed (header <type_traits>) kiểm tra xem kiểu T có phải là kiểu có dấu (signed type) hay không.
Kiểu signed trong C++
- Tất cả signed integer types:
signed char,short,int,long,long long(và aliasint8_t...). - Tất cả floating-point types:
float,double,long double(vì có thể biểu diễn giá trị âm).
KHÔNG phải signed: unsigned integer, bool, class, enum, pointer, void.
Cú pháp
template <class T> struct is_signed;
Ví dụ 1: Kiểm tra cơ bản
#include <iostream>
#include <type_traits>
using namespace std;
class TP { };
enum TP_1 : int { };
enum class TP_2 : int { };
int main() {
cout << boolalpha;
cout << "Kiểm tra is_signed:\n";
cout << "int: " << is_signed<int>::value << '\n'; // true
cout << "TP (class): " << is_signed<TP>::value << '\n'; // false
cout << "TP_1 (enum): " << is_signed<TP_1>::value << '\n'; // false
cout << "TP_2 (enum class): " << is_signed<TP_2>::value << '\n'; // false
return 0;
}
Đầu ra
Kiểm tra is_signed: int: true TP (class): false TP_1 (enum): false TP_2 (enum class): false
Ví dụ 2: Floating-point và unsigned
#include <iostream>
#include <type_traits>
using namespace std;
int main() {
cout << boolalpha;
cout << "float: " << is_signed<float>::value << '\n'; // true
cout << "signed int: " << is_signed<signed int>::value << '\n'; // true
cout << "unsigned int: " << is_signed<unsigned int>::value << '\n'; // false
cout << "double: " << is_signed<double>::value << '\n'; // true
cout << "long double: " << is_signed<long double>::value << '\n'; // true
cout << "int8_t: " << is_signed<int8_t>::value << '\n'; // true
cout << "uint8_t: " << is_signed<uint8_t>::value << '\n'; // false
return 0;
}
Đầu ra
float: true signed int: true unsigned int: false double: true long double: true int8_t: true uint8_t: false
Mối quan hệ
Đối với integer types (integral):
is_signed XOR is_unsigned // Luôn true cho integer type (trừ bool, char có thể implementation-defined)
Đối với floating-point: is_signed == true, is_unsigned == false.
Ứng dụng
- Template constraints: Yêu cầu signed type cho phép giá trị âm.
- Static assert ngăn chặn unsigned overflow logic.
- SFINAE overload cho signed vs unsigned.
Lưu ý quan trọng
bool:is_signed=false,is_unsigned=false(kiểu logic, không phải integer).char: Implementation-defined (signed hoặc unsigned). Dùngsigned char/unsigned charđể chắc chắn.- Enum: Phụ thuộc underlying type.
enum E : int→ signed;enum E : unsigned int→ unsigned. - C++20: Concept
std::signed_integral.