6

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.

johnbakers
  • 24,158
  • 24
  • 130
  • 258
  • 1
    Please take any discussion about the appropriateness of this question to [the meta question](http://meta.stackoverflow.com/questions/315498/do-questions-about-code-oddities-need-a-mcve), but the OP is right: a question asking about how to do something does not necessarily require an MCVE for it to stay open. I'll say more in meta. Shog9 [talked about this in this meta post](http://meta.stackoverflow.com/questions/306368/should-a-howto-question-about-launching-c-threads-be-closed-for-lacking-an-mcv). – George Stocker Jan 26 '16 at 20:08
  • 1
    @GeorgeStocker Retracted now. You're right I've been arguing about that earlier, and been proved wrong. – πάντα ῥεῖ Jan 26 '16 at 20:16

3 Answers3

6
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.
ildjarn
  • 62,044
  • 9
  • 127
  • 211
  • This seems like a work around. The important question is why does the OP's code not work? – R Sahu Jan 26 '16 at 18:36
  • 1
    @RSahu : This is not a workaround, it is the corrected code. – ildjarn Jan 26 '16 at 18:37
  • This indeed solved the problem, many thanks. I was missing the extra braces. I thought in C++14 they were no longer necessary, but I might have misunderstood that detail.s Thanks! – johnbakers Jan 26 '16 at 18:45
  • @johnbakers : In this case they can be elided for the inner arrays ([demo](http://coliru.stacked-crooked.com/a/107f3902b02a771f)), but the outer array requires both. – ildjarn Jan 26 '16 at 18:56
  • 1
    @ildjarn, it seemed to me to be a workaround since there was no explanation of whey the OP's code didn't work. I understand now why it isn't a work around. – R Sahu Jan 26 '16 at 19:23
3

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

NathanOliver
  • 171,901
  • 28
  • 288
  • 402
3

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.

Community
  • 1
  • 1
R Sahu
  • 204,454
  • 14
  • 159
  • 270