Brace elision in std::array












6















I'm compiling using g++ for C++ 17. I have the following:



std::array<std::vector<int>, 2> v = {{ {1,2}, {3,4} }};


I don't understand why if I remove the double braces for the array it does not work anymore.



std::array<std::vector<int>, 2> v = { {1,2}, {3,4} }; // Does not compile


I understand how std::array works and the need for the double braces in general, but as I'm compiling for C++17 I expected brace elision to come into play.



Why is brace elision not applicable here?










share|improve this question




















  • 1





    What do you mean by "not working" - the code compiles with GCC 8.1.0 and -std=c++17

    – Neil Butterworth
    Nov 14 '18 at 17:36








  • 1





    @NeilButterworth He meant about this. If I understood correctly.

    – JeJo
    Nov 14 '18 at 17:39













  • @JeJo Yes you are correct.

    – Svalorzen
    Nov 14 '18 at 17:40











  • @JeJo That code isn't compiled with -std=c++17

    – Neil Butterworth
    Nov 14 '18 at 17:41













  • @NeilButterworth g++ -std=c++17 main.cpp main.cpp: In function ‘int main()’: main.cpp:5:56: error: too many initializers for ‘std::array<std::vector<int>, 2>’ std::array<std::vector<int>, 2> v = { {1,2}, {3,4} };

    – Svalorzen
    Nov 14 '18 at 17:43
















6















I'm compiling using g++ for C++ 17. I have the following:



std::array<std::vector<int>, 2> v = {{ {1,2}, {3,4} }};


I don't understand why if I remove the double braces for the array it does not work anymore.



std::array<std::vector<int>, 2> v = { {1,2}, {3,4} }; // Does not compile


I understand how std::array works and the need for the double braces in general, but as I'm compiling for C++17 I expected brace elision to come into play.



Why is brace elision not applicable here?










share|improve this question




















  • 1





    What do you mean by "not working" - the code compiles with GCC 8.1.0 and -std=c++17

    – Neil Butterworth
    Nov 14 '18 at 17:36








  • 1





    @NeilButterworth He meant about this. If I understood correctly.

    – JeJo
    Nov 14 '18 at 17:39













  • @JeJo Yes you are correct.

    – Svalorzen
    Nov 14 '18 at 17:40











  • @JeJo That code isn't compiled with -std=c++17

    – Neil Butterworth
    Nov 14 '18 at 17:41













  • @NeilButterworth g++ -std=c++17 main.cpp main.cpp: In function ‘int main()’: main.cpp:5:56: error: too many initializers for ‘std::array<std::vector<int>, 2>’ std::array<std::vector<int>, 2> v = { {1,2}, {3,4} };

    – Svalorzen
    Nov 14 '18 at 17:43














6












6








6


1






I'm compiling using g++ for C++ 17. I have the following:



std::array<std::vector<int>, 2> v = {{ {1,2}, {3,4} }};


I don't understand why if I remove the double braces for the array it does not work anymore.



std::array<std::vector<int>, 2> v = { {1,2}, {3,4} }; // Does not compile


I understand how std::array works and the need for the double braces in general, but as I'm compiling for C++17 I expected brace elision to come into play.



Why is brace elision not applicable here?










share|improve this question
















I'm compiling using g++ for C++ 17. I have the following:



std::array<std::vector<int>, 2> v = {{ {1,2}, {3,4} }};


I don't understand why if I remove the double braces for the array it does not work anymore.



std::array<std::vector<int>, 2> v = { {1,2}, {3,4} }; // Does not compile


I understand how std::array works and the need for the double braces in general, but as I'm compiling for C++17 I expected brace elision to come into play.



Why is brace elision not applicable here?







c++ c++17 list-initialization






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 14 '18 at 17:41







Svalorzen

















asked Nov 14 '18 at 17:32









SvalorzenSvalorzen

3,30521746




3,30521746








  • 1





    What do you mean by "not working" - the code compiles with GCC 8.1.0 and -std=c++17

    – Neil Butterworth
    Nov 14 '18 at 17:36








  • 1





    @NeilButterworth He meant about this. If I understood correctly.

    – JeJo
    Nov 14 '18 at 17:39













  • @JeJo Yes you are correct.

    – Svalorzen
    Nov 14 '18 at 17:40











  • @JeJo That code isn't compiled with -std=c++17

    – Neil Butterworth
    Nov 14 '18 at 17:41













  • @NeilButterworth g++ -std=c++17 main.cpp main.cpp: In function ‘int main()’: main.cpp:5:56: error: too many initializers for ‘std::array<std::vector<int>, 2>’ std::array<std::vector<int>, 2> v = { {1,2}, {3,4} };

    – Svalorzen
    Nov 14 '18 at 17:43














  • 1





    What do you mean by "not working" - the code compiles with GCC 8.1.0 and -std=c++17

    – Neil Butterworth
    Nov 14 '18 at 17:36








  • 1





    @NeilButterworth He meant about this. If I understood correctly.

    – JeJo
    Nov 14 '18 at 17:39













  • @JeJo Yes you are correct.

    – Svalorzen
    Nov 14 '18 at 17:40











  • @JeJo That code isn't compiled with -std=c++17

    – Neil Butterworth
    Nov 14 '18 at 17:41













  • @NeilButterworth g++ -std=c++17 main.cpp main.cpp: In function ‘int main()’: main.cpp:5:56: error: too many initializers for ‘std::array<std::vector<int>, 2>’ std::array<std::vector<int>, 2> v = { {1,2}, {3,4} };

    – Svalorzen
    Nov 14 '18 at 17:43








1




1





What do you mean by "not working" - the code compiles with GCC 8.1.0 and -std=c++17

– Neil Butterworth
Nov 14 '18 at 17:36







What do you mean by "not working" - the code compiles with GCC 8.1.0 and -std=c++17

– Neil Butterworth
Nov 14 '18 at 17:36






1




1





@NeilButterworth He meant about this. If I understood correctly.

– JeJo
Nov 14 '18 at 17:39







@NeilButterworth He meant about this. If I understood correctly.

– JeJo
Nov 14 '18 at 17:39















@JeJo Yes you are correct.

– Svalorzen
Nov 14 '18 at 17:40





@JeJo Yes you are correct.

– Svalorzen
Nov 14 '18 at 17:40













@JeJo That code isn't compiled with -std=c++17

– Neil Butterworth
Nov 14 '18 at 17:41







@JeJo That code isn't compiled with -std=c++17

– Neil Butterworth
Nov 14 '18 at 17:41















@NeilButterworth g++ -std=c++17 main.cpp main.cpp: In function ‘int main()’: main.cpp:5:56: error: too many initializers for ‘std::array<std::vector<int>, 2>’ std::array<std::vector<int>, 2> v = { {1,2}, {3,4} };

– Svalorzen
Nov 14 '18 at 17:43





@NeilButterworth g++ -std=c++17 main.cpp main.cpp: In function ‘int main()’: main.cpp:5:56: error: too many initializers for ‘std::array<std::vector<int>, 2>’ std::array<std::vector<int>, 2> v = { {1,2}, {3,4} };

– Svalorzen
Nov 14 '18 at 17:43












2 Answers
2






active

oldest

votes


















7














std::array<std::vector<int>, 2> is effectively



struct array {
std::vector<int> elems[2];
};


elems is a subaggregate just fine. The issue is that per the language rules, if the initializer starts with a { it's always assumed that you aren't eliding braces; instead, {1, 2} is taken as the initializer of the entire subaggregate elems, attempting to initialize its first element with 1 and second element with 2 (this is obviously invalid - you can't convert an integer to a vector - but doesn't affect the interpretation), and {3, 4} is considered the initializer for the thing after elems - and since there are no such thing, it's another error.



Initializing the first element with something that's not a braced-init-list is sufficient to trigger brace elision:



std::array<std::vector<int>, 2> v = { std::vector<int>{1,2}, {3,4} }; 




Note that from a specification perspective, the library doesn't guarantee initialization of std::array<T, N> from anything other than another std::array<T, N> or a list of "up to N elements whose types are convertible to T". This notably excludes braced-init-lists because they have no type, and actually also disallows "double braces" because that's just a special case of having a single element that is a braced-init-list .



This is an area where we may have been better off specifying it with code. The core language rules defy easy specification in words and the implementation details will leak out - and have already done so.






share|improve this answer


























  • Thank you for the clarification, it was very useful. I'm not sure I fully understood your second remark though. The initialization is not guaranteed in other cases means that it is unspecified behaviour? Why are also double braces disallowed (considering that the brace elision rule was made pretty much for std::array IIUC)?

    – Svalorzen
    Nov 14 '18 at 20:49






  • 2





    Formally, it's undefined behavior: the standard defines no behavior when a std::array is initialized with anything else. Double braces are not in the "defined to work" case because they are actually an initializer list containing a single element (the inner braced-init-list) with no type. Brace elision goes all the way back to C. std::array has nothing to do with it. The formal UB here is certainly a defect; the problem is finding the right words to define the behavior, preferably without regurgitating the several pages of aggregate initialization rules.

    – T.C.
    Nov 14 '18 at 23:52





















4














As T.C. pointed out my original interpretation was not corret, brace elision is allowed see [dcl.init.aggr]p15:




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. ...




but std::array according to array.overview:




An array is an aggregate that can be list-initialized with up to N elements whose types are convertible to T.




which is not the case we have.






share|improve this answer


























  • But in my example the double brace is only required for std::array, which is an an aggregate, right? Or is brace elision only allowed when it's aggregate all the way down?

    – Svalorzen
    Nov 14 '18 at 17:55











  • I just noticed that std::array<std::vector<int>, 2> v = {std::vector<int>{1,2}, std::vector<int>{3,4}}; compiles. Is this also the "does not begin with a left brace" case?

    – Svalorzen
    Nov 14 '18 at 18:01








  • 1





    @Svalorzen that is a different case of explicit initialization covered by dcl.init.aggrp3.2 and dcl.init.aggrp4.2)

    – Shafik Yaghmour
    Nov 14 '18 at 18:25











  • OP's example is attempting to elide the braces for the std::vector<int>[2] subaggregate.

    – T.C.
    Nov 14 '18 at 20:05











  • @T.C. so are you saying it should work and the compilers are non-conforming or that my choice of words is not correct or that it should not work but I am quoting the wrong parts?

    – Shafik Yaghmour
    Nov 14 '18 at 20:09













Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53305831%2fbrace-elision-in-stdarraystdvector%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes









7














std::array<std::vector<int>, 2> is effectively



struct array {
std::vector<int> elems[2];
};


elems is a subaggregate just fine. The issue is that per the language rules, if the initializer starts with a { it's always assumed that you aren't eliding braces; instead, {1, 2} is taken as the initializer of the entire subaggregate elems, attempting to initialize its first element with 1 and second element with 2 (this is obviously invalid - you can't convert an integer to a vector - but doesn't affect the interpretation), and {3, 4} is considered the initializer for the thing after elems - and since there are no such thing, it's another error.



Initializing the first element with something that's not a braced-init-list is sufficient to trigger brace elision:



std::array<std::vector<int>, 2> v = { std::vector<int>{1,2}, {3,4} }; 




Note that from a specification perspective, the library doesn't guarantee initialization of std::array<T, N> from anything other than another std::array<T, N> or a list of "up to N elements whose types are convertible to T". This notably excludes braced-init-lists because they have no type, and actually also disallows "double braces" because that's just a special case of having a single element that is a braced-init-list .



This is an area where we may have been better off specifying it with code. The core language rules defy easy specification in words and the implementation details will leak out - and have already done so.






share|improve this answer


























  • Thank you for the clarification, it was very useful. I'm not sure I fully understood your second remark though. The initialization is not guaranteed in other cases means that it is unspecified behaviour? Why are also double braces disallowed (considering that the brace elision rule was made pretty much for std::array IIUC)?

    – Svalorzen
    Nov 14 '18 at 20:49






  • 2





    Formally, it's undefined behavior: the standard defines no behavior when a std::array is initialized with anything else. Double braces are not in the "defined to work" case because they are actually an initializer list containing a single element (the inner braced-init-list) with no type. Brace elision goes all the way back to C. std::array has nothing to do with it. The formal UB here is certainly a defect; the problem is finding the right words to define the behavior, preferably without regurgitating the several pages of aggregate initialization rules.

    – T.C.
    Nov 14 '18 at 23:52


















7














std::array<std::vector<int>, 2> is effectively



struct array {
std::vector<int> elems[2];
};


elems is a subaggregate just fine. The issue is that per the language rules, if the initializer starts with a { it's always assumed that you aren't eliding braces; instead, {1, 2} is taken as the initializer of the entire subaggregate elems, attempting to initialize its first element with 1 and second element with 2 (this is obviously invalid - you can't convert an integer to a vector - but doesn't affect the interpretation), and {3, 4} is considered the initializer for the thing after elems - and since there are no such thing, it's another error.



Initializing the first element with something that's not a braced-init-list is sufficient to trigger brace elision:



std::array<std::vector<int>, 2> v = { std::vector<int>{1,2}, {3,4} }; 




Note that from a specification perspective, the library doesn't guarantee initialization of std::array<T, N> from anything other than another std::array<T, N> or a list of "up to N elements whose types are convertible to T". This notably excludes braced-init-lists because they have no type, and actually also disallows "double braces" because that's just a special case of having a single element that is a braced-init-list .



This is an area where we may have been better off specifying it with code. The core language rules defy easy specification in words and the implementation details will leak out - and have already done so.






share|improve this answer


























  • Thank you for the clarification, it was very useful. I'm not sure I fully understood your second remark though. The initialization is not guaranteed in other cases means that it is unspecified behaviour? Why are also double braces disallowed (considering that the brace elision rule was made pretty much for std::array IIUC)?

    – Svalorzen
    Nov 14 '18 at 20:49






  • 2





    Formally, it's undefined behavior: the standard defines no behavior when a std::array is initialized with anything else. Double braces are not in the "defined to work" case because they are actually an initializer list containing a single element (the inner braced-init-list) with no type. Brace elision goes all the way back to C. std::array has nothing to do with it. The formal UB here is certainly a defect; the problem is finding the right words to define the behavior, preferably without regurgitating the several pages of aggregate initialization rules.

    – T.C.
    Nov 14 '18 at 23:52
















7












7








7







std::array<std::vector<int>, 2> is effectively



struct array {
std::vector<int> elems[2];
};


elems is a subaggregate just fine. The issue is that per the language rules, if the initializer starts with a { it's always assumed that you aren't eliding braces; instead, {1, 2} is taken as the initializer of the entire subaggregate elems, attempting to initialize its first element with 1 and second element with 2 (this is obviously invalid - you can't convert an integer to a vector - but doesn't affect the interpretation), and {3, 4} is considered the initializer for the thing after elems - and since there are no such thing, it's another error.



Initializing the first element with something that's not a braced-init-list is sufficient to trigger brace elision:



std::array<std::vector<int>, 2> v = { std::vector<int>{1,2}, {3,4} }; 




Note that from a specification perspective, the library doesn't guarantee initialization of std::array<T, N> from anything other than another std::array<T, N> or a list of "up to N elements whose types are convertible to T". This notably excludes braced-init-lists because they have no type, and actually also disallows "double braces" because that's just a special case of having a single element that is a braced-init-list .



This is an area where we may have been better off specifying it with code. The core language rules defy easy specification in words and the implementation details will leak out - and have already done so.






share|improve this answer















std::array<std::vector<int>, 2> is effectively



struct array {
std::vector<int> elems[2];
};


elems is a subaggregate just fine. The issue is that per the language rules, if the initializer starts with a { it's always assumed that you aren't eliding braces; instead, {1, 2} is taken as the initializer of the entire subaggregate elems, attempting to initialize its first element with 1 and second element with 2 (this is obviously invalid - you can't convert an integer to a vector - but doesn't affect the interpretation), and {3, 4} is considered the initializer for the thing after elems - and since there are no such thing, it's another error.



Initializing the first element with something that's not a braced-init-list is sufficient to trigger brace elision:



std::array<std::vector<int>, 2> v = { std::vector<int>{1,2}, {3,4} }; 




Note that from a specification perspective, the library doesn't guarantee initialization of std::array<T, N> from anything other than another std::array<T, N> or a list of "up to N elements whose types are convertible to T". This notably excludes braced-init-lists because they have no type, and actually also disallows "double braces" because that's just a special case of having a single element that is a braced-init-list .



This is an area where we may have been better off specifying it with code. The core language rules defy easy specification in words and the implementation details will leak out - and have already done so.







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 14 '18 at 23:54

























answered Nov 14 '18 at 20:19









T.C.T.C.

107k14219323




107k14219323













  • Thank you for the clarification, it was very useful. I'm not sure I fully understood your second remark though. The initialization is not guaranteed in other cases means that it is unspecified behaviour? Why are also double braces disallowed (considering that the brace elision rule was made pretty much for std::array IIUC)?

    – Svalorzen
    Nov 14 '18 at 20:49






  • 2





    Formally, it's undefined behavior: the standard defines no behavior when a std::array is initialized with anything else. Double braces are not in the "defined to work" case because they are actually an initializer list containing a single element (the inner braced-init-list) with no type. Brace elision goes all the way back to C. std::array has nothing to do with it. The formal UB here is certainly a defect; the problem is finding the right words to define the behavior, preferably without regurgitating the several pages of aggregate initialization rules.

    – T.C.
    Nov 14 '18 at 23:52





















  • Thank you for the clarification, it was very useful. I'm not sure I fully understood your second remark though. The initialization is not guaranteed in other cases means that it is unspecified behaviour? Why are also double braces disallowed (considering that the brace elision rule was made pretty much for std::array IIUC)?

    – Svalorzen
    Nov 14 '18 at 20:49






  • 2





    Formally, it's undefined behavior: the standard defines no behavior when a std::array is initialized with anything else. Double braces are not in the "defined to work" case because they are actually an initializer list containing a single element (the inner braced-init-list) with no type. Brace elision goes all the way back to C. std::array has nothing to do with it. The formal UB here is certainly a defect; the problem is finding the right words to define the behavior, preferably without regurgitating the several pages of aggregate initialization rules.

    – T.C.
    Nov 14 '18 at 23:52



















Thank you for the clarification, it was very useful. I'm not sure I fully understood your second remark though. The initialization is not guaranteed in other cases means that it is unspecified behaviour? Why are also double braces disallowed (considering that the brace elision rule was made pretty much for std::array IIUC)?

– Svalorzen
Nov 14 '18 at 20:49





Thank you for the clarification, it was very useful. I'm not sure I fully understood your second remark though. The initialization is not guaranteed in other cases means that it is unspecified behaviour? Why are also double braces disallowed (considering that the brace elision rule was made pretty much for std::array IIUC)?

– Svalorzen
Nov 14 '18 at 20:49




2




2





Formally, it's undefined behavior: the standard defines no behavior when a std::array is initialized with anything else. Double braces are not in the "defined to work" case because they are actually an initializer list containing a single element (the inner braced-init-list) with no type. Brace elision goes all the way back to C. std::array has nothing to do with it. The formal UB here is certainly a defect; the problem is finding the right words to define the behavior, preferably without regurgitating the several pages of aggregate initialization rules.

– T.C.
Nov 14 '18 at 23:52







Formally, it's undefined behavior: the standard defines no behavior when a std::array is initialized with anything else. Double braces are not in the "defined to work" case because they are actually an initializer list containing a single element (the inner braced-init-list) with no type. Brace elision goes all the way back to C. std::array has nothing to do with it. The formal UB here is certainly a defect; the problem is finding the right words to define the behavior, preferably without regurgitating the several pages of aggregate initialization rules.

– T.C.
Nov 14 '18 at 23:52















4














As T.C. pointed out my original interpretation was not corret, brace elision is allowed see [dcl.init.aggr]p15:




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. ...




but std::array according to array.overview:




An array is an aggregate that can be list-initialized with up to N elements whose types are convertible to T.




which is not the case we have.






share|improve this answer


























  • But in my example the double brace is only required for std::array, which is an an aggregate, right? Or is brace elision only allowed when it's aggregate all the way down?

    – Svalorzen
    Nov 14 '18 at 17:55











  • I just noticed that std::array<std::vector<int>, 2> v = {std::vector<int>{1,2}, std::vector<int>{3,4}}; compiles. Is this also the "does not begin with a left brace" case?

    – Svalorzen
    Nov 14 '18 at 18:01








  • 1





    @Svalorzen that is a different case of explicit initialization covered by dcl.init.aggrp3.2 and dcl.init.aggrp4.2)

    – Shafik Yaghmour
    Nov 14 '18 at 18:25











  • OP's example is attempting to elide the braces for the std::vector<int>[2] subaggregate.

    – T.C.
    Nov 14 '18 at 20:05











  • @T.C. so are you saying it should work and the compilers are non-conforming or that my choice of words is not correct or that it should not work but I am quoting the wrong parts?

    – Shafik Yaghmour
    Nov 14 '18 at 20:09


















4














As T.C. pointed out my original interpretation was not corret, brace elision is allowed see [dcl.init.aggr]p15:




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. ...




but std::array according to array.overview:




An array is an aggregate that can be list-initialized with up to N elements whose types are convertible to T.




which is not the case we have.






share|improve this answer


























  • But in my example the double brace is only required for std::array, which is an an aggregate, right? Or is brace elision only allowed when it's aggregate all the way down?

    – Svalorzen
    Nov 14 '18 at 17:55











  • I just noticed that std::array<std::vector<int>, 2> v = {std::vector<int>{1,2}, std::vector<int>{3,4}}; compiles. Is this also the "does not begin with a left brace" case?

    – Svalorzen
    Nov 14 '18 at 18:01








  • 1





    @Svalorzen that is a different case of explicit initialization covered by dcl.init.aggrp3.2 and dcl.init.aggrp4.2)

    – Shafik Yaghmour
    Nov 14 '18 at 18:25











  • OP's example is attempting to elide the braces for the std::vector<int>[2] subaggregate.

    – T.C.
    Nov 14 '18 at 20:05











  • @T.C. so are you saying it should work and the compilers are non-conforming or that my choice of words is not correct or that it should not work but I am quoting the wrong parts?

    – Shafik Yaghmour
    Nov 14 '18 at 20:09
















4












4








4







As T.C. pointed out my original interpretation was not corret, brace elision is allowed see [dcl.init.aggr]p15:




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. ...




but std::array according to array.overview:




An array is an aggregate that can be list-initialized with up to N elements whose types are convertible to T.




which is not the case we have.






share|improve this answer















As T.C. pointed out my original interpretation was not corret, brace elision is allowed see [dcl.init.aggr]p15:




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. ...




but std::array according to array.overview:




An array is an aggregate that can be list-initialized with up to N elements whose types are convertible to T.




which is not the case we have.







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 14 '18 at 21:35

























answered Nov 14 '18 at 17:52









Shafik YaghmourShafik Yaghmour

126k23326539




126k23326539













  • But in my example the double brace is only required for std::array, which is an an aggregate, right? Or is brace elision only allowed when it's aggregate all the way down?

    – Svalorzen
    Nov 14 '18 at 17:55











  • I just noticed that std::array<std::vector<int>, 2> v = {std::vector<int>{1,2}, std::vector<int>{3,4}}; compiles. Is this also the "does not begin with a left brace" case?

    – Svalorzen
    Nov 14 '18 at 18:01








  • 1





    @Svalorzen that is a different case of explicit initialization covered by dcl.init.aggrp3.2 and dcl.init.aggrp4.2)

    – Shafik Yaghmour
    Nov 14 '18 at 18:25











  • OP's example is attempting to elide the braces for the std::vector<int>[2] subaggregate.

    – T.C.
    Nov 14 '18 at 20:05











  • @T.C. so are you saying it should work and the compilers are non-conforming or that my choice of words is not correct or that it should not work but I am quoting the wrong parts?

    – Shafik Yaghmour
    Nov 14 '18 at 20:09





















  • But in my example the double brace is only required for std::array, which is an an aggregate, right? Or is brace elision only allowed when it's aggregate all the way down?

    – Svalorzen
    Nov 14 '18 at 17:55











  • I just noticed that std::array<std::vector<int>, 2> v = {std::vector<int>{1,2}, std::vector<int>{3,4}}; compiles. Is this also the "does not begin with a left brace" case?

    – Svalorzen
    Nov 14 '18 at 18:01








  • 1





    @Svalorzen that is a different case of explicit initialization covered by dcl.init.aggrp3.2 and dcl.init.aggrp4.2)

    – Shafik Yaghmour
    Nov 14 '18 at 18:25











  • OP's example is attempting to elide the braces for the std::vector<int>[2] subaggregate.

    – T.C.
    Nov 14 '18 at 20:05











  • @T.C. so are you saying it should work and the compilers are non-conforming or that my choice of words is not correct or that it should not work but I am quoting the wrong parts?

    – Shafik Yaghmour
    Nov 14 '18 at 20:09



















But in my example the double brace is only required for std::array, which is an an aggregate, right? Or is brace elision only allowed when it's aggregate all the way down?

– Svalorzen
Nov 14 '18 at 17:55





But in my example the double brace is only required for std::array, which is an an aggregate, right? Or is brace elision only allowed when it's aggregate all the way down?

– Svalorzen
Nov 14 '18 at 17:55













I just noticed that std::array<std::vector<int>, 2> v = {std::vector<int>{1,2}, std::vector<int>{3,4}}; compiles. Is this also the "does not begin with a left brace" case?

– Svalorzen
Nov 14 '18 at 18:01







I just noticed that std::array<std::vector<int>, 2> v = {std::vector<int>{1,2}, std::vector<int>{3,4}}; compiles. Is this also the "does not begin with a left brace" case?

– Svalorzen
Nov 14 '18 at 18:01






1




1





@Svalorzen that is a different case of explicit initialization covered by dcl.init.aggrp3.2 and dcl.init.aggrp4.2)

– Shafik Yaghmour
Nov 14 '18 at 18:25





@Svalorzen that is a different case of explicit initialization covered by dcl.init.aggrp3.2 and dcl.init.aggrp4.2)

– Shafik Yaghmour
Nov 14 '18 at 18:25













OP's example is attempting to elide the braces for the std::vector<int>[2] subaggregate.

– T.C.
Nov 14 '18 at 20:05





OP's example is attempting to elide the braces for the std::vector<int>[2] subaggregate.

– T.C.
Nov 14 '18 at 20:05













@T.C. so are you saying it should work and the compilers are non-conforming or that my choice of words is not correct or that it should not work but I am quoting the wrong parts?

– Shafik Yaghmour
Nov 14 '18 at 20:09







@T.C. so are you saying it should work and the compilers are non-conforming or that my choice of words is not correct or that it should not work but I am quoting the wrong parts?

– Shafik Yaghmour
Nov 14 '18 at 20:09




















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53305831%2fbrace-elision-in-stdarraystdvector%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Bressuire

Vorschmack

Quarantine