在 C++11 中使用(阴影)base-class 数据成员初始化结构

Initialize struct with (shadowed) base-class data members in C++11

可以向 shadow 基础 class 的派生 struct 同名成员添加成员,无论这是否是一个错误由 another Q&A 解决。我的问题是关于初始化隐藏的继承成员。 is-a 关系允许派生 D 到基 class B 的按值赋值,但很难 初始化 继承成员对应于基础 class。在下面的示例中,B 的初始化是使用大括号括起来的初始化列表完成的,但这对于 D 是不可能的。我找到的用于定义 D 实例的唯一选项是默认初始化(零)并在之后分配:

#include <iostream>
using namespace std;

int main()
{
    struct B { int x; };
    struct D: B { int x; };
    B bas = {1};
    cout << bas.x << endl;
    D der = {};
    der.x = 2;
    bas = der;
    cout << bas.x << endl;
    der.B::x = 3;
    bas = der;
    cout << bas.x << endl;
    static_cast<B&>(der).x = 4;
    bas = der;
    cout << bas.x << endl;
    return 0;
}

输出:

1
0
3
4

以下我认为可能可行的想法导致了编译器错误:

    D der = {1, 2};

error: could not convert '{1, 2}' from '<brace-enclosed initializer list>' to 'main()::D'

    D der = {B::x=1, 2};

error: invalid use of non-static data member 'main()::B::x'

error: could not convert '{<expression error>, 2}' from '<brace-enclosed initializer list>' to 'main()::D'

(g++.exe -Weffc++ -pedantic -Wextra -Wall -std=gnu++11 -std=c++11 -fexceptions -g -std=c++11 使用 gcc 8.1.0)

有没有在 C++11 中正确初始化的方法?

附录:
当我问这个问题时,我非常关注访问影子成员的困难,以至于我完全错过了 C++11 中 aggregate initialization 的有限选项。所以这个问题的答案也适用于没有隐藏数据成员的派生 classes。

D der = {1, 2} 可以在 C++17 中工作,因为

D der = {{42}, 2};

Demo

对于之前的版本,你不能像这样初始化基类,你需要一个构造函数。