为何添加普通构造函数会使MyPair不再是字面量类型?
问题原因解析
首先明确C++中**字面量类型(literal type)**的核心判定规则,针对类类型主要有两种符合情况:
- 类是聚合类,且所有非静态数据成员都是字面量类型;
- 类不是聚合类,但满足:
- 拥有至少一个
constexpr构造函数(拷贝/移动构造除外); - 所有非静态数据成员都是字面量类型;
- 没有虚函数或虚基类;
- 析构函数是平凡的等次要条件。
- 拥有至少一个
1. 添加MyPair(const A& first, const B& second)构造函数后的情况
当你添加这个自定义构造函数后:
- MyPair不再是聚合类:聚合类要求不能有用户声明的构造函数,自定义构造函数的存在直接打破了这一条件。
- 这个自定义构造函数没有被声明为
constexpr:此时MyPair既不是聚合类,也没有符合要求的constexpr构造函数,因此不再属于字面量类型。 - 代码
constexpr MyPair<int,int> ssss=[](){return MyPair<int,int>{5,3};}();要求MyPair<int,int>是字面量类型,同时lambda返回的对象必须是常量表达式构造的,但自定义构造函数不是constexpr,无法在常量表达式上下文使用,因此编译失败。
2. 移除构造函数后的情况
移除自定义构造函数后:
- MyPair成为聚合类:没有用户声明的构造函数,所有成员都是
int(字面量类型),满足聚合类的判定条件,因此属于字面量类型。 - 隐式生成的默认构造函数是
constexpr:对于聚合类,当所有非静态成员都是字面量类型时,编译器隐式生成的默认构造函数会被自动视为constexpr构造函数。 - 代码中的lambda操作符合
constexpr上下文要求:C++14及以后,constexpr函数(包括constexprlambda)中允许修改非const的constexpr变量的成员,因此re.first=5;是合法操作,最终整个初始化过程是有效的常量表达式,所以编译通过。
内容的提问来源于stack exchange,提问作者cppBeginner
相关产品推荐
相关产品推荐

