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_poddeprecated, dùng tổ hợpis_trivial+is_standard_layout.