Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Excess elements in struct initializer when nested std::array

Tags:

c++

c++11

I'm getting Excess elements in struct initializer on the return line of the following:

using triangleColor = std::array<std::array<float, 4>, 3>;

triangleColor colorBlend(TriangleColorBlend c){
    switch (c) {
        case TriangleColorBlend::white:
            return {{1.0,1.0,1.0,1.0},{0.7,0.7,0.7,1.0},{0.5,0.5,0.5,1.0}};
            break;

        ... // other cases
    }
}

I was hoping the curly-brace literal would work in the nested fashion, as it works fine if I do this with just a single std::array, not nested.

Is the above simply not possible, and why not?

Note, the suggested duplicate doesn't really address the odd behavior of std::array in a nested situation.

like image 761
johnbakers Avatar asked Jan 26 '16 18:01

johnbakers


People also ask

What does excess elements in scalar initializer mean?

The excess elements in scalar initializer is an error thrown when a scalar object is assigned more than one value. Remember that scalar objects are objects that only hold one value at a time.

How many union members can be initialised?

A union can be initialized on its declaration. Because only one member can be used at a time, only one can be initialized. To avoid confusion, only the first member of the union can be initialized.

How to initialize union in c++?

A union can have a constructor to initialize any of its members. A union without a constructor can be initialized with another union of the same type, with an expression of the type of the first member of the union, or with an initializer (enclosed in braces) of the type of the first member of the union.

How to initialize structure in Cpp?

// In C++ We can Initialize the Variables with Declaration in Structure. Structure members can be initialized using curly braces '{}'.


3 Answers

triangleColor colorBlend(TriangleColorBlend c) {
    switch (c) {
    case TriangleColorBlend::white:
        return {{
            {{ 1.0f, 1.0f, 1.0f, 1.0f }},
            {{ 0.7f, 0.7f, 0.7f, 1.0f }},
            {{ 0.5f, 0.5f, 0.5f, 1.0f }}
        }};
    default:
        throw std::invalid_argument("c");
    }
}

Online Demo

There were two issues with your code:

  1. You were lacking braces for the inner arrays.
  2. As noted by @Praetorian, colorBlend had no return value for the default case.
like image 110
ildjarn Avatar answered Oct 18 '22 00:10

ildjarn


You are missing a set of brackets.

return {{1.0,1.0,1.0,1.0},{0.7,0.7,0.7,1.0},{0.5,0.5,0.5,1.0}};

Should be

return {{{1.0,1.0,1.0,1.0},{0.7,0.7,0.7,1.0},{0.5,0.5,0.5,1.0}}};

You can see it working in this minimal example

like image 38
NathanOliver Avatar answered Oct 18 '22 00:10

NathanOliver


Another work around:

triangleColor colorBlend(TriangleColorBlend c){
   using t1 = std::array<float, 4>;
   switch (c) {
      case TriangleColorBlend::white:
         return {t1{1.0,1.0,1.0,1.0},t1{0.7,0.7,0.7,1.0},t1{0.5,0.5,0.5,1.0}};
         break;

      default:
         break;
   }
   return triangleColor{};
}

The answer to the question of why

        return {{1.0,1.0,1.0,1.0},{0.7,0.7,0.7,1.0},{0.5,0.5,0.5,1.0}};

does not work can be found at https://stackoverflow.com/a/8192275/434551:

std::array is an aggregate by the rules of C++11, and therefore it can be created by aggregate initialization. To aggregate initialize the array inside the struct, you need a second set of curly braces.

like image 2
R Sahu Avatar answered Oct 18 '22 01:10

R Sahu