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

Template is_standard_layout trong C++ STL

std::is_standard_layout (header <type_traits>) kiểm tra xem kiểu T có phải là standard layout type hay không. Standard layout type có bố cục bộ nhớ đơn giản, dự đoán được, tương thích C, và hỗ trợ offsetof.

Điều kiện Standard Layout Class

  • Không có virtual function và không có virtual base class.
  • Tất cả non-static data member có cùng access control (đều public, hoặc đều private, hoặc đều protected).
  • Không có non-static data member trong base class (chỉ derived class có data member, hoặc chỉ base class có).
  • Không có base class cùng kiểu với first non-static data member.
  • Tất cả base class và non-static data member đều là standard layout.

Cú pháp

template <class T> struct is_standard_layout;

Ví dụ 1: Kiểm tra các kiểu

#include <iostream>
#include <type_traits>
using namespace std;

class TP { int var; };                    // Standard layout
struct TP_2 { int var; private: int v2; }; // KHÔNG: access control khác nhau
union TP_3 { };                           // Standard layout

int main() {
    cout << boolalpha;
    cout << "TP (class, 1 var):     " << is_standard_layout<TP>::value << '\n';     // true
    cout << "TP_2 (struct, mixed):  " << is_standard_layout<TP_2>::value << '\n';  // false
    cout << "TP_3 (union):          " << is_standard_layout<TP_3>::value << '\n';   // true
    cout << "char:                  " << is_standard_layout<char>::value << '\n';     // true
    cout << "int:                   " << is_standard_layout<int>::value << '\n';       // true
    return 0;
}

Đầu ra

TP (class, 1 var):     true
TP_2 (struct, mixed):  false
TP_3 (union):          true
char:                  true
int:                   true

Ví dụ 2: Kế thừa và access control

#include <iostream>
#include <type_traits>
using namespace std;

class Base { int x; };              // Standard layout
class Derived1 : Base { int y; };   // KHÔNG: cả Base và Derived có non-static member
class Derived2 : Base { };          // Standard layout: chỉ Base có member
class MixedAccess { public: int a; private: int b; }; // KHÔNG: access khác nhau

int main() {
    cout << boolalpha;
    cout << "Base:         " << is_standard_layout<Base>::value << '\n';         // true
    cout << "Derived1:     " << is_standard_layout<Derived1>::value << '\n';     // false
    cout << "Derived2:     " << is_standard_layout<Derived2>::value << '\n';     // true
    cout << "MixedAccess:  " << is_standard_layout<MixedAccess>::value << '\n';  // false
    cout << "int*:         " << is_standard_layout<int*>::value << '\n';         // true
    cout << "float:        " << is_standard_layout<float>::value << '\n';        // true
    return 0;
}

Đầu ra

Base:         true
Derived1:     false
Derived2:     true
MixedAccess:  false
int*:         true
float:        true

Tại sao quan trọng?

  • C Compatibility: Có thể chia sẻ với C code (struct tương đương).
  • offsetof: Chỉ hoạt động với standard layout type.
  • Memory layout: Đảm bảo thứ tự member theo khai báo, không padding lạ.
  • Union an toàn: Chỉ standard layout type được phép trong union (C++11).
  • memcpy: An toàn cho standard layout + trivially copyable.

Mối quan hệ

is_standard_layout && is_trivial  ≡  is_pod (C++11, deprecated C++20)

Lưu ý

  • Kiểu cơ bản (int, float, pointer...) luôn là standard layout.
  • Array của standard layout cũng là standard layout.
  • C++20: is_pod deprecated, dùng tổ hợp is_trivial + is_standard_layout.