std::is_empty (header <type_traits>) kiểm tra xem một kiểu T có phải là lớp rỗng (empty class) hay không. Lớp rỗng là lớp không chứa dữ liệu non-static.
Điều kiện Empty Class
- Không có non-static data member (trừ bit-field độ dài 0).
- Không có virtual function.
- Không có virtual base class.
- Không có base class non-empty.
Lưu ý: Static data member, typedef, enum, hàm thành viên (non-virtual) KHÔNG làm class trở nên non-empty.
Cú pháp
template <class T> struct is_empty;
Ví dụ kiểm tra
#include <iostream>
#include <type_traits>
using namespace std;
class Empty1 { }; // Rỗng
class Empty2 { static int x; }; // Rỗng (static member)
class Empty3 { void foo() {} }; // Rỗng (non-virtual function)
class Empty4 { ~Empty4() {} }; // Rỗng (user destructor nhưng không virtual)
class NonEmpty1 { int x; }; // Non-empty: có non-static member
class NonEmpty2 { virtual void f(); };// Non-empty: virtual function
class NonEmpty3 : Empty1 { int y; }; // Non-empty: có member
struct SEmpty { }; // Struct cũng áp dụng
struct SNonEmpty { int x; }; // Non-empty
int main() {
cout << boolalpha;
cout << "Kiểm tra is_empty (class):\n";
cout << "Empty1: " << is_empty<Empty1>::value << '\n'; // true
cout << "Empty2: " << is_empty<Empty2>::value << '\n'; // true
cout << "Empty3: " << is_empty<Empty3>::value << '\n'; // true
cout << "Empty4: " << is_empty<Empty4>::value << '\n'; // true
cout << "NonEmpty1: " << is_empty<NonEmpty1>::value << '\n'; // false
cout << "NonEmpty2: " << is_empty<NonEmpty2>::value << '\n'; // false
cout << "NonEmpty3: " << is_empty<NonEmpty3>::value << '\n'; // false
cout << "\nKiểm tra is_empty (struct):\n";
cout << "SEmpty: " << is_empty<SEmpty>::value << '\n'; // true
cout << "SNonEmpty: " << is_empty<SNonEmpty>::value << '\n'; // false
// Kiểu cơ bản
cout << "\nKiểu cơ bản:\n";
cout << "int: " << is_empty<int>::value << '\n'; // false
cout << "void: " << is_empty<void>::value << '\n'; // false
return 0;
}
Đầu ra
Kiểm tra is_empty (class): Empty1: true Empty2: true Empty3: true Empty4: true NonEmpty1: false NonEmpty2: false NonEmpty3: false Kiểm tra is_empty (struct): SEmpty: true SNonEmpty: false Kiểu cơ bản: int: false void: false
Empty Base Optimization (EBO)
Compiler tối ưu hóa kích thước đối tượng khi kế thừa từ empty class:
struct Empty { };
struct Derived : Empty { int x; };
// sizeof(Derived) == sizeof(int) (thường là 4)
// Empty base không chiếm bộ nhớ thêm!
Ứng dụng
- EBO: Tiết kiệm bộ nhớ cho policy-based design, mixin.
- Template metaprogramming: Đặc biệt hóa cho empty type.
- Type traits: Kết hợp với
is_trivial,is_standard_layout.
Lưu ý
is_emptychỉ định nghĩa cho class type. Với non-class type luôn false.- C++20:
[[no_unique_address]]attribute cho phép EBO cho member variable (không chỉ base class).