初始化固定长度的C数组成员结构体

4

我有一个非常简单的POD结构体,包含下面的数组成员。我遇到了初始化固定长度数组成员memberArray的问题,使用了一个引用固定长度数组参数const uint32_t(&rArrayArg)[22]。在最终目标环境中,我将无法访问标准库。

成员初始化值memberArray{*rArrayArg}只会复制rArrayArg参数的第一个条目。为了看到完整的数组,我需要在构造函数的主体中进行memcpy或者(如本例所示)std::copy。

我还有另一个POD结构体,接受一个二维固定长度数组const uint32_t(&rArrayArg)[4][5]用于初始化相应的2d成员,则更倾向于成员初始化语法的通用解决方案。

struct TestStruct {
    explicit TestStruct(
        const uint32_t(&rArrayArg)[22])
        : memberArray{*rArrayArg}
    {
        //std::copy(std::cbegin(rArrayArg), std::cend(rArrayArg), memberArray);
    }

    uint32_t memberArray[22];

    // this stream helper is only present for debugging purposes
    // in the actual target environment, I will not have access to std:: 
    friend std::ostream& operator<<(std::ostream& os, const TestStruct& rhs) {
        os << "TestStruct: ";
        for (auto next : rhs.memberArray) {
            os << next << ",";
        }
        return os;
    }
};

以下实时演示展示了将部分填充的固定数组参数uint32_t fixedLenArg[22] = {1,2,3,4,5,6};传递给显式构造函数的结果。打印结果如下:
TestStruct: 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,

很明显只有第一个参数被复制了。 如果我在构造函数体中取消 std::copy 的注释(这是调试,因为在最终环境中我无法访问 std::copy),我会得到以下结果:

TestStruct: 1,2,3,4,5,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,

1
那么明确一点,你既不能使用 std::copy 也不能使用 std::memcpy?如果是这种情况,你可能需要自己编写代码,或者使用 for 循环进行复制,或者实现你自己的复制方法。 - Cory Kramer
@CoryKramer 实际上我将有访问memcpy的权限,但我的真正问题是如何避免使用它或在成员初始化中使用它(而不是在构造函数体中使用)。 - johnco3
1
这个回答解决了你的问题吗? - Cory Kramer
@CoryKramer +1,你接近了但还不太对,我需要能够传递一个固定数组类型引用的左值 - 我认为有一些语法可以通过某些我不知道的语法技巧来完整地复制这个数组。 - johnco3
2个回答

3

我希望我理解这个问题的正确性,那么这应该可以解决:

struct TestStruct {
  constexpr static size_t arraySize = 22;

  explicit TestStruct(const uint32_t(&rArrayArg)[arraySize]) : memberArray() {
    for (size_t i = 0; i < arraySize; ++i)
        memberArray[i] = rArrayArg[i];
  }

  uint32_t memberArray[arraySize];

  // this stream helper is only present for debugging purposes
  // in the actual target environment, I will not have access to std::
  friend std::ostream& operator<<(std::ostream& os, const TestStruct& rhs) {
    os << "TestStruct: ";
    for (auto next : rhs.memberArray) {
      os << next << ",";
    }
    return os;
  }
};

2
很好。顺便说一下,我建议放弃使用sizeof技巧,改用static constexpr std::size_t n = 22; - StoryTeller - Unslander Monica
这也可以很容易地推广到二维情况。如果代码重用是一个问题,它也可以轻松地提取到一个函数中。+1 - Max Langhof

2
如果您被允许使用std::array,那么这将变得非常简单:
struct TestStruct { 
    explicit TestStruct(std::array<uint32_t, 22> const& rArrayArg)
        : memberArray{rArrayArg}
    {}

    std::array<uint32_t, 22> memberArray;

    // this stream helper is only present for debugging purposes
    // in the actual target environment, I will not have access to std:: 
    friend std::ostream& operator<<(std::ostream& os, const TestStruct& rhs) {
        os << "TestStruct: ";
        for (auto next : rhs.memberArray) {
            os << next << ",";
        }
        return os;
    }
};
std::array的内置复制构造函数将完成所有必要的工作。

请阅读我的问题,最终目标环境中将无法访问STL标准库。 - johnco3
@johnco3,你不应该将问题标记为C++11,因为这意味着可以访问STL。 - Xirema
2
@Xirema - 独立实现不需要拥有大部分标准库。这是完全有效的C++11。 - StoryTeller - Unslander Monica

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接