【问题标题】:Static initializing a struct of unions of arrays静态初始化数组联合的结构
【发布时间】:2014-08-05 21:22:10
【问题描述】:

我正在尝试为这个类编写静态初始化器:

class Cube3x3
{
    union CornerData
    {
        u8  mData8[8];
        u32 mData16[4];
        u32 mData32[2];
        u64 mData64;
    };

    union EdgeData
    {
        u8  mData8[12];
        u32 mData32[3];
    };

    CornerData mCorners;
    EdgeData mEdges;

    static const Cube3x3 sSolved;
};

我已经尝试过这个,还有很多变种,似乎我尝试的任何方法都行不通。

const Cube3x3 Cube3x3::sSolved =
{
    { 0, 0, 1, 0, 0, 0, 1, 0 },
    { 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 }
};

有谁知道如何或是否可以静态初始化它?

【问题讨论】:

    标签: c++ unions static-initialization static-initializer


    【解决方案1】:

    如果你愿意将Cube3x3从一个类改成一个结构,你可以使用:

    const Cube3x3 Cube3x3::sSolved = {0};
    

    更新

    当使用结构时,您还可以使用非零值初始化成员,就像您在更新后的问题中一样。

    const Cube3x3 Cube3x3::sSolved =
    {
        { 0, 0, 1, 0, 0, 0, 1, 0 },
        { 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0 }
    };
    

    【讨论】:

    • 对不起,我真的不想将它归零,我实际上有大量的枚举值进入这里,我不想粘贴到问题中。我会尽力澄清。
    • 当 Cube3x3 是类或结构时,您提供的代码 sn-p 无法编译,至少在 VS2013 上不会编译,这就是我发布问题的原因。是我的编译器有问题吗?
    • @VoidStar,这是我的猜测。在ideone.com/AWUc4v 处查看工作版本。
    • 好吧,我犯了一个错误,它确实适用于 VS2013 中的 struct。那是我犯的核心错误,我认为 class 在静态初始化语法方面的行为与 struct 相同,但显然情况并非如此。
    • 实际上,类和结构都允许静态初始化语法!真正的罪魁祸首是,显然您不能静态初始化受保护/私有成员变量!所以只要一切都是公开的,你就可以在类上使用这种语法!
    【解决方案2】:

    一种解决方案是使用 C++11 lambda 对其进行初始化。

    const Cube3x3 Cube3x3::sSolved = []{
        Cube3x3 cube;
        std::fill(std::begin(cube.mCorners.mData8), std::end(cube.mCorners.mData8), 0);
        std::fill(std::begin(cube.mEdges.mData8), std::end(cube.mEdges.mData8), 0);
    
        return cube;
    }();
    

    Live Example

    请注意末尾的(),这表明我们正在调用该 lambda 函数。如果您使用的是非 C++11 编译器,或者至少一个尚不支持 C++11 lambda 的编译器,您可以编写一个与编写 lambda 时具有基本相同主体的函数。然后,您需要在静态初始化所需对象时调用该函数。

    Cube3x3 initialize() {
        Cube3x3 cube;
        std::fill(&cube.mCorners.mData8[0], &cube.mCorners.mData8[8], 0);
        std::fill(&cube.mEdges.mData8[0], &cube.mEdges.mData8[8], 0);
    
        return cube;
    }
    
    
    const Cube3x3 Cube3x3::sSolved = initialize();
    

    Live Example

    【讨论】:

    • 这几乎是一个不错的解决方法,但是 mCorners 和 mEdges 受 Cube3x3 保护,这几乎排除了 lambdas。我想我也可以使用您的答案的第二个版本,使用会员朋友或会员功能......我现在可能不得不这样做。
    【解决方案3】:

    如果我为您的类添加一个以 CornerData 和 EdgeData 作为参数的构造函数,则该代码对我有用。

    Cube3x3(CornerData cornerData, EdgeData edgeData) 
                            : mCorners(cornerData), 
                              mEdges(edgeData)
    {
    }
    

    这里是链接:http://ideone.com/XzBXZM

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-10-07
      • 2021-01-31
      • 2013-09-22
      • 1970-01-01
      • 2017-09-17
      • 1970-01-01
      • 2011-02-08
      • 2023-04-05
      相关资源
      最近更新 更多