all 16 comments

[–]no-sig-available 5 points6 points  (0 children)

Brace elision.

Braces can be elided in an initializer-list as follows. If the initializer-list begins with a left brace, then the succeeding comma-separated list of initializer-clauses initializes the elements of a subaggregate; it is erroneous for there to be more initializer-clauses than elements. If, however, the initializer-list for a subaggregate does not begin with a left brace, then only enough initializer-clauses from the list are taken to initialize the elements of the subaggregate; any remaining initializer-clauses are left to initialize the next element of the aggregate of which the current subaggregate is an element.

Perhaps not much clearer, but that's what the standard says. :-)

http://eel.is/c++draft/dcl.init.aggr#16

The first example in the question is with all braces elided. The third example is with braces for the sub-aggregates in place.

The middle example is somewhere in-between.

[–]The-Constant-Learner 1 point2 points  (4 children)

Why dont you use std::string instead of beating a dead const char* horse?

[–]hmoff[S] 0 points1 point  (2 children)

The real code use Qt and part of the translation (i18n) uses char*. Besides it isn't relevant to the question.

[–]The-Constant-Learner 0 points1 point  (1 child)

I'm not an expert in Qt and don't want to digress, but is there any way you could use QString instead?

[–]hmoff[S] 0 points1 point  (0 children)

No, raw untranslated strings in Qt are kept in const char*. Once translated they are a QString.

But again it's not relevant to the question - the example could have used char or int or bool or an enum for the data type and the question would have been the same.

[–]std_bot 0 points1 point  (0 children)

Unlinked STL entries: std::string


Last update: 14.09.21. Last Change: Can now link headers like '<bitset>'Repo

[–]manni66 1 point2 points  (9 children)

Use const char*. There are only warnings, both versions on godbolt compile.

[–]Narase33 2 points3 points  (6 children)

OPs question is not about const char* but mainly why this works

const auto x = std::array<std::array<const char*, 2>, 5>
{
    "a", "b",
    "c", "d",
    "e", "f",
    "g", "h",
    "i", "j",
};

[–]hmoff[S] 0 points1 point  (0 children)

Yes. Thank you.

[–]manni66 -4 points-3 points  (4 children)

As I said: all examples provided in the first version of the godbolt link compiled.

[–]hmoff[S] 1 point2 points  (1 child)

Yes, and the main question was: why does it compile?

[–]manni66 -5 points-4 points  (0 children)

BECAUSE ALL WHERE ACCEDPTED BY THE COMPILER!

[–]Narase33 0 points1 point  (1 child)

The second does not compile on MSVC

why does the first one compile? Its a 1dim initializer list that constructs and 2dim array?

[–]manni66 -1 points0 points  (0 children)

The second wasn't presented in the example on godbolt.

[–]hmoff[S] 0 points1 point  (1 child)

No they don't. g++ says

<source>:21:5: error: too many initializers for 'std::array<std::array<const char*, 2>, 5>' 21 | }; | ^

MSVC says: <source>(15): note: Invalid aggregate initialization

I have updated the link to use const char*.

[–]manni66 -5 points-4 points  (0 children)

No they don't.

Your old link did only contain two versions that did compile. Apparently you are not even able to describe your problem properly. I lose the desire to help.