Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> C++

Template is_empty trong C++ STL

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_empty chỉ đị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).