나는이 질문이 오래되었다는 것을 알고 있지만 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...
그런 다음 const 속성을 가진 구조체가 있으면 다음과 같이 할 수 있습니다.
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.);
가능한 많은 수의 속성에 대한 매크로가 필요하고 매크로 호출에서 인스턴스의 유형과 이름을 반복해야하기 때문에 약간 불편합니다. 또한 어설 션이 초기화 후에 오기 때문에 매크로를 return 문에 사용할 수 없습니다.
그러나 그것은 문제를 해결합니다 : 구조체를 변경하면 컴파일 타임에 호출이 실패합니다.
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);\