4

I have a very simple POD struct containing an array member shown below. I am having problems initializing the fixed length array member memberArray with a reference fixed length array parameter const uint32_t(&rArrayArg)[22]. I will not have access to the standard library in the final target environment.

The member initializer memberArray{*rArrayArg} only copies the first entry from the rArrayArg arg. In order to see the complete array, I need to memcpy or (as shown here) std::copy in the body of the constructor.

I have another POD struct that takes a 2 dimensional fixed length array const uint32_t(&rArrayArg)[4][5] which will be used to initialize a corresponding 2d member, so a general solution for the member initialization syntax would be preferred.

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;
    }
};

The following live demo shows the result of passing a partially populated fixed array parameter uint32_t fixedLenArg[22] = {1,2,3,4,5,6}; to the explicit constructor. Printing the results shows:

TestStruct: 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,

so clearly only the first parameter is being copied. If I uncomment the std::copy in the body of the constructor (this is debug as I do not have access to std::copy in the final environment) I get the following:

TestStruct: 1,2,3,4,5,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
johnco3
  • 2,401
  • 4
  • 35
  • 67
  • 1
    So to be clear you can neither `std::copy` nor `std::memcpy`? If that's the case might need to roll your own, either copy in a for loop or implement your own copy method – Cory Kramer May 14 '18 at 14:22
  • @CoryKramer Actually I will have access to memcpy but my real question is how to avoid that or use it in the member initialization (as opposed to in the body of the constructor) – johnco3 May 14 '18 at 14:26
  • 1
    Does [this](https://stackoverflow.com/questions/4057948/initializing-a-member-array-in-constructor-initializer) answer your question? – Cory Kramer May 14 '18 at 14:27
  • @CoryKramer +1 for getting close but its not quite what I need, I need to be able to pass in an lvalue of a fixed array type reference - I thought that there was some syntax where this array could be copied in its entirety via some syntax trick I am unaware of. – johnco3 May 14 '18 at 14:43

2 Answers2

3

I hope I understood the problem correctly, then this should work:

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;
  }
};
Yuki
  • 3,857
  • 5
  • 25
  • 43
2

If you're allowed to use std::array, this becomes pretty trivial:

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;
    }
};

The built-in copy constructor for std::array will do all the work that needs to take place.

Xirema
  • 19,889
  • 4
  • 32
  • 68