मुझे पता है कि यह प्रश्न पुराना है, लेकिन इसे हल करने का एक तरीका है जब तक कि C ++ 20 अंत में C से C ++ तक यह सुविधा नहीं लाता है। आप इसे हल करने के लिए क्या कर सकते हैं अपने इनिशियलाइज़ेशन को मान्य करने के लिए static_asserts के साथ प्रीप्रोसेसर मैक्रोज़ का उपयोग करें। (मुझे पता है कि मैक्रोज़ आम तौर पर खराब होते हैं, लेकिन यहां मुझे दूसरा रास्ता नहीं दिखता।) नीचे उदाहरण कोड देखें:
#define INVALID_STRUCT_ERROR "Instantiation of struct failed: Type, order or number of attributes is wrong."
#define CREATE_STRUCT_1(type, identifier, m_1, p_1) \
{ p_1 };\
static_assert(offsetof(type, m_1) == 0, INVALID_STRUCT_ERROR);\
#define CREATE_STRUCT_2(type, identifier, m_1, p_1, m_2, p_2) \
{ p_1, p_2 };\
static_assert(offsetof(type, m_1) == 0, INVALID_STRUCT_ERROR);\
static_assert(offsetof(type, m_2) >= sizeof(identifier.m_1), INVALID_STRUCT_ERROR);\
#define CREATE_STRUCT_3(type, identifier, m_1, p_1, m_2, p_2, m_3, p_3) \
{ p_1, p_2, p_3 };\
static_assert(offsetof(type, m_1) == 0, INVALID_STRUCT_ERROR);\
static_assert(offsetof(type, m_2) >= sizeof(identifier.m_1), INVALID_STRUCT_ERROR);\
static_assert(offsetof(type, m_3) >= (offsetof(type, m_2) + sizeof(identifier.m_2)), INVALID_STRUCT_ERROR);\
#define CREATE_STRUCT_4(type, identifier, m_1, p_1, m_2, p_2, m_3, p_3, m_4, p_4) \
{ p_1, p_2, p_3, p_4 };\
static_assert(offsetof(type, m_1) == 0, INVALID_STRUCT_ERROR);\
static_assert(offsetof(type, m_2) >= sizeof(identifier.m_1), INVALID_STRUCT_ERROR);\
static_assert(offsetof(type, m_3) >= (offsetof(type, m_2) + sizeof(identifier.m_2)), INVALID_STRUCT_ERROR);\
static_assert(offsetof(type, m_4) >= (offsetof(type, m_3) + sizeof(identifier.m_3)), INVALID_STRUCT_ERROR);\
// Create more macros for structs with more attributes...
तब जब आपके पास कास्ट विशेषताओं के साथ एक संरचना होती है, तो आप यह कर सकते हैं:
struct MyStruct
{
const int attr1;
const float attr2;
const double attr3;
};
const MyStruct test = CREATE_STRUCT_3(MyStruct, test, attr1, 1, attr2, 2.f, attr3, 3.);
यह थोड़ा असुविधाजनक है, क्योंकि आपको हर संभव संख्या के लिए मैक्रोज़ की आवश्यकता है और आपको मैक्रो कॉल में अपने उदाहरण के प्रकार और नाम को दोहराने की आवश्यकता है। इसके अलावा, आप मैक्रो का उपयोग रिटर्न स्टेटमेंट में नहीं कर सकते हैं, क्योंकि आरंभीकरण आरम्भ होने के बाद आता है।
लेकिन यह आपकी समस्या को हल करता है: जब आप संरचना बदलते हैं, तो संकलन-समय पर कॉल विफल हो जाएगी।
यदि आप C ++ 17 का उपयोग करते हैं, तो आप इन मैक्रों को समान प्रकारों के लिए बाध्य करके और भी सख्त बना सकते हैं, जैसे:
#define CREATE_STRUCT_3(type, identifier, m_1, p_1, m_2, p_2, m_3, p_3) \
{ p_1, p_2, p_3 };\
static_assert(offsetof(type, m_1) == 0, INVALID_STRUCT_ERROR);\
static_assert(offsetof(type, m_2) >= sizeof(identifier.m_1), INVALID_STRUCT_ERROR);\
static_assert(offsetof(type, m_3) >= (offsetof(type, m_2) + sizeof(identifier.m_2)), INVALID_STRUCT_ERROR);\
static_assert(typeid(p_1) == typeid(identifier.m_1), INVALID_STRUCT_ERROR);\
static_assert(typeid(p_2) == typeid(identifier.m_2), INVALID_STRUCT_ERROR);\
static_assert(typeid(p_3) == typeid(identifier.m_3), INVALID_STRUCT_ERROR);\