Рассмотрим следующий сегмент кода:
#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
(текущее и определение, закомментированное ввоспроизводится исходный код.)
Я просмотрел следующие страницы с целью понимания происходящего здесь:
спецификатор constexpr (начиная с C ++ 11)
Постоянные выражения
Я должен признать, что не могу понять, почему список инициализатора элемента является обязательным в случае конструктора для A, а нев случае B.
цените ваши мысли.