2

I have this definitions:

typedef uint8_t myType[16];

constexpr myType x0 = {1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6};
constexpr myType x1 = {11,12,13,14,15,16,17,18,19,10,11,12,13,14,15,16};
constexpr myType x2 = {21,22,23,24,25,26,27,28,29,20,21,22,23,24,25,26};

constexpr myType AllX[] = {x0,x1,x2};

compiling this in VS 2015, give me this error:

An internal error has occurred in the compiler. 

The intelisense report this error:

a value of type "const uint8_t *" cannot be used to initialize an entity of type "const uint8_t"

How can I fix this problem?

1
  • If you absolutely have to have things flattened, there's this. Commented May 22, 2018 at 15:05

3 Answers 3

2

You can use std::array to get around the problem.

#include <array>

using myType = std::array<uint8_t, 16>;

int main()
{
   constexpr myType x0={1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6};
   constexpr myType x1={11,12,13,14,15,16,17,18,19,10,11,12,13,14,15,16};
   constexpr myType x2={21,22,23,24,25,26,27,28,29,20,21,22,23,24,25,26};

   constexpr std::array<myType, 3> AllX = {x0,x1,x2};
}

In a comment, you said,

But I can not use this method as x0 and x1 and x2 and .. is already defined in that way in code and I can not change it.

In that case, your only option is to copy the elements of those objects to AllX. You can use std::copy to streamline that. The only problem is that you can't use constexpr AllX.

   std::array<myType, 3> AllX = {};
   std::copy(begin(x0), end(x0), AllX[0].data());
   std::copy(begin(x1), end(x1), AllX[1].data());
   std::copy(begin(x2), end(x2), AllX[2].data());
Sign up to request clarification or add additional context in comments.

2 Comments

AllX can then be treated as a single flat C-style array with AllX.data(), right?
@hegel5000 That works for a single std::array object. I am not sure about a nested std::array object. I'll have to try it out to be sure.
0

An array can only be initialized with a brace-enclosed initializer, not with another array. See aggregate initialization for more details.

A fix:

constexpr myType AllX[] = {
    {1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6},
    {11,12,13,14,15,16,17,18,19,10,11,12,13,14,15,16},
    {21,22,23,24,25,26,27,28,29,20,21,22,23,24,25,26}
};

constexpr auto& x0=AllX[0];
constexpr auto& x1=AllX[1];
constexpr auto& x2=AllX[2];

1 Comment

Thanks, But I can not use this method as x0 and x1 and x2 and .. is already defined in that way in code and I can not change it. As they are constexpr, they are resolved during compile time. Is there any way that we can extract them for initializing the all array?
0

In C, you can declare AllX[] as an array of pointers to the underlying members. This will lose the compiler knowledge that they are of size 16, but I don't know how important that is to you. And of course you /can/ do that in c++:

constexpr uint8_t *AllX[]={x0,x1,x2};

To demonstrate the loss, you could write it as:

constexpr uint8_t *AllX[]={&x0[0],&x1[0],&x2[0]};

You would index this using 2 sets of [], e.g. AllX[1][5]

Alternatively, you could declare a lightweight object that takes references to a fixed number of myType objects in its constructor, and provides an operator overload to perform the outer indexing. Internally that object might as well have a C-array or std::array of pointers to mytype, and step through that pointer. You could probably extend this to a template function that generates a template class to allow the two arrays to have compile-time determined sizes.

This object could also take ownership of the child arrays, calling some destruction method on the members from its own destruction.

When you are talking about a single flat array, are you saying you want AllX[25 to find X1[9]? If so, you could do that with the lightweight wrapper object operator. It could perform the necessary trivial math on the index to get the outer and inner indices, and return a (const) reference to the relevant member.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.