【问题标题】:seeking clarification on constexpr function寻求对 constexpr 函数的澄清
【发布时间】:2020-02-10 02:53:28
【问题描述】:

考虑以下代码段:

#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 specifier (since C++11)

Constant expressions

我必须承认,我无法弄清楚为什么在 A 的构造函数的情况下,成员初始化器列表是强制性的,而不是在 B 的情况下。

欣赏你的想法。

【问题讨论】:

    标签: c++ function c++11 constexpr


    【解决方案1】:

    A 有一个默认构造函数(顺便说一下,constexpr)。 constexpr构造函数that you are citing的相关要求如下:

    对于类或结构的构造函数,...每个非变体 必须初始化非静态数据成员。

    它是“初始化”的唯一要求。不是“显式初始化”。默认构造函数将满足初始化要求。 A 有一个默认构造函数。所以你的Ba类成员被它的默认构造函数初始化,满足这个要求,所以你不必在B的构造函数的初始化列表中显式地初始化它。

    另一方面,您的花园品种int 没有默认构造函数。因此,Aconstexpr 构造函数必须显式初始化它。

    【讨论】:

      猜你喜欢
      • 2023-03-23
      • 2018-10-10
      • 1970-01-01
      • 2017-10-29
      • 1970-01-01
      • 1970-01-01
      • 2021-08-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多