c++ - 寻求对 constexpr 函数的澄清
问题描述
考虑以下代码段:
#include <iostream>
using std::cout;
using std::endl;
class A
{
public:
//constexpr A (){i = 0;}
constexpr A ():i(0){}
void show (void){cout << i << endl; return;}
private:
int i;
};
class B
{
public:
constexpr B(A a){this->a = a;}
//constexpr B(A a):a(a){}
void show (void){a.show(); return;}
private:
A a;
};
int main (void)
{
A a;
B b(a);
b.show();
return (0);
}
在 的定义中class A
,如果当前构造函数定义被注释掉的定义替换:
//constexpr A (){i = 0;}
出现以下编译错误(请注意,行号对应于原始代码):
g++ -ggdb -std=c++17 -Wall -Werror=pedantic -Wextra -c code.cpp
code.cpp: In constructor ‘constexpr A::A()’:
code.cpp:8:30: error: member ‘A::i’ must be initialized by mem-initializer in ‘constexpr’ constructor
constexpr A (){i = 0;}
^
code.cpp:12:13: note: declared here
int i;
^
make: *** [makefile:20: code.o] Error 1
但是,代码与构造函数的任一定义完美编译class B
(当前以及在复制的源代码中注释掉的定义。)
我查看了以下页面,目的是了解这里发生了什么:
我必须承认,我无法弄清楚为什么在 A 的构造函数的情况下,成员初始化程序列表是强制性的,而不是在 B 的情况下。
欣赏你的想法。
解决方案
A
有一个默认构造函数(constexpr
顺便说一句)。您引用constexpr
的构造函数的相关要求如下:
对于类或结构的构造函数,...必须初始化每个非变体非静态数据成员。
唯一的要求是“初始化”。不是“显式初始化”。默认构造函数将满足初始化要求。A
有一个默认构造函数。所以你B
的a
类成员被它的默认构造函数初始化,满足这个要求,所以你不必在B
构造函数的初始化列表中显式地初始化它。
另一方面,您的花园品种int
没有默认构造函数。因此,A
的constexpr
构造函数必须显式初始化它。
推荐阅读
- java - JVM中的日期更改
- android - 无法在 Firebase 数据库的用户 ID 文件夹中创建新路径
- json - 从 ruby 中的 json 数组中的 json 获取值
- jquery - 使用带有 for 循环的 javascript 解析 Json
- image - SVG存储和操作
- python - VS Code Python 测试调试超时
- ios - 在 iOS 13 和 iOS 11.4 中从字符串转换日期的不同结果
- mysql - 这是编写此 MySQL 语句的最有效方法吗?
- git - `go install`-ing私有包时如何输入git repo用户名?
- reactjs - 无法在 Redux + Firebase 中获取用户描述