C++11中结构体含默认初始化值时如何使用列表初始化?
C++11中带成员默认值的结构体花括号初始化解决方案
问题原因
C++11对聚合体的定义有严格限制:如果结构体/类的非静态成员带有类内默认初始化器,它就不再被视为聚合体。而你用的LR0Item Q{"test", test_v, 3};属于聚合初始化语法,仅适用于聚合体,因此编译器会提示找不到匹配的构造函数。
解决方法
显式为结构体添加匹配参数的构造函数,让花括号列表初始化转为调用构造函数:
// 假设test_v是TestV类型的枚举值 enum class TestV { Default, ... }; struct LR0Item { // 保留成员默认初始化值 std::string name = ""; TestV val = TestV::Default; int num = 0; // 添加与初始化参数匹配的构造函数 LR0Item(std::string n, TestV v, int m) : name(std::move(n)), val(v), num(m) {} // 如果需要默认构造能力,显式声明默认构造函数 // 因为自定义构造函数后,编译器不会自动生成默认构造 LR0Item() = default; }; // 现在可以正常编译 LR0Item Q{"test", test_v, 3};
如果不想保留类内默认值的写法,也可以把默认值移到默认构造函数的初始化列表中,同样能实现需求:
struct LR0Item { std::string name; TestV val; int num; // 默认构造函数设置成员默认值 LR0Item() : name(""), val(TestV::Default), num(0) {} // 带参数的构造函数 LR0Item(std::string n, TestV v, int m) : name(std::move(n)), val(v), num(m) {} }; // 同样可以正常初始化 LR0Item Q{"test", test_v, 3};
注意事项
- C14及以后放宽了聚合体的定义,允许成员带有类内默认初始化器,此时可以直接用聚合初始化。但在C11标准下必须通过构造函数解决。
- 自定义构造函数后,若需要创建无参的默认实例(比如
LR0Item empty;),必须显式声明LR0Item() = default;或自定义默认构造函数。
内容的提问来源于stack exchange,提问作者sdbbs
相关产品推荐
相关产品推荐

