为何这段代码在C++11下编译报错,C++14及以上却可正常编译?
问题原因
C11与C14对聚合类型的定义存在关键差异:
- 在C++11中,若结构体包含默认成员初始化器(即代码里
char* cmd = nullptr;这种给成员赋默认值的写法),则该结构体不再被视为聚合类型,无法使用聚合初始化(也就是{ "test", nullptr }这种直接用大括号初始化对象的方式)。 - C++14修改了聚合类型的判定规则,允许带有默认成员初始化器的结构体仍被认定为聚合类型,因此可以正常使用聚合初始化。
你的代码在C++11环境下报错,本质是尝试用聚合初始化去初始化一个非聚合类型的结构体,编译器无法完成转换。
解决方案
你可以通过以下几种方式解决这个问题:
方案1:移除默认成员初始化器
让结构体在C++11中成为聚合类型,即可正常使用聚合初始化:
typedef void (*cmdH)(const char* args, const uint8_t argCnt); struct CMDList { char* cmd; /**< @brief Command C-string. */ cmdH cmdHandler; /**< @brief Pointer to command function. See \ref cmdH */ }; CMDList list[2] = { { "test", nullptr }, { "hello", nullptr } };
方案2:添加构造函数
为结构体显式定义构造函数,通过构造函数完成初始化:
typedef void (*cmdH)(const char* args, const uint8_t argCnt); struct CMDList { char* cmd = nullptr; cmdH cmdHandler = nullptr; // 显式构造函数 CMDList(char* c, cmdH handler) : cmd(c), cmdHandler(handler) {} }; CMDList list[2] = { CMDList("test", nullptr), CMDList("hello", nullptr) };
方案3:切换到C++14及更高编译标准
直接将编译器的编译标准切换为C++14或更高版本,原代码即可正常编译。
内容的提问来源于stack exchange,提问作者Pararera
相关产品推荐
相关产品推荐

