Path: csiph.com!eternal-september.org!feeder.eternal-september.org!reader01.eternal-september.org!.POSTED!not-for-mail From: Tim Rentsch Newsgroups: comp.lang.c++ Subject: Re: Initialization of std::vector throws Date: Wed, 18 Sep 2019 08:37:31 -0700 Organization: A noiseless patient Spider Lines: 92 Message-ID: <86blvh4nus.fsf@linuxsc.com> References: Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Injection-Info: reader02.eternal-september.org; posting-host="d7421874ff1696044f351dbc5e408957"; logging-data="28854"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+pdWFZOUMHmZflBV6StWhGd51oNivEaxg=" User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.4 (gnu/linux) Cancel-Lock: sha1:FwWxIoyB0MJTSX2naRnvJpnFqQg= sha1:0wwgLBzfmK9W0EWu8J94G8VuIzU= Xref: csiph.com comp.lang.c++:68505 Pavel writes: > Ralf Goertz wrote: > >> Am Wed, 04 Sep 2019 08:20:51 -0400 >> schrieb Sam : >> >>> Ralf Goertz writes: >>> >>>> why does the declaration >>>> >>>> std::vector pt({{"One","Two"}}); >>>> >>>> throw: >>>> >>>> terminate called after throwing an instance of 'std::length_error' >>>> what(): basic_string::_M_create >>> >>> Because this is undefined behavior. >>> >>>> whereas neither >>>> >>>> std::vector pt({{"One"}}); >>>> >>>> nor >>>> >>>> std::vector pt({{1,2}}); >>> >>> If you actually examine the end result the last declaration, you will >>> discover, to your surprise, a std::vector with just one value, >>> and that would hopefully be a big honking clue as to what this is >>> doing. >> >> Hm, I did that and it failed to surprise me. >> >> >> #include >> #include >> #include >> >> std::vector pt({{1,2}}); >> int main() { >> for (auto p:pt) std::cout<> } >> >> gives: >> 1 >> 2 > > my guess is the above pt declarator is roughly equivalent to > pt(vector(initializer_list(initializer_list(1,2)))) -- > which just happens to give you an expected result. I think it is > undefined or implementation-specific what default copy constructor does > on initializer_list because the data members of it are not defined by > the standard. This seems wrong to me. Please note I am not saying it IS wrong, only that it seems to me to be wrong. More specifically I don't think undefined behavior plays a role. I tried reading the Standard to verify that but found it impenetrable in this area. Can someone help find the relevant passages (and an accompanying explanation would also be appreciated)? >> here. Just as I expected. >> >>> { /* something */ } introduces a braced initialization list. >>> >>> { { /* something */ } } introduces a braced initialization list with >>> one value. >> >> But didn't we need to use two braces for container intialization? > > for vector, because there is constructor with count and value, you > need something like = { 1, 2}; (note =) for {1,2} to be interpreted as > initializer_list; for vector you should be able to initialize > with {"One", "Two"} directly. I'm pretty sure what you say about vector isn't right. A declaration like vector foo { 10, 1 }; gives a vector of length 2, not a vector of length 10. If the braces were parentheses vector bas ( 10, 1 ); we would get a vector of length 10, using the ( count, value ) constructor. Disclaimer: the comments above are based solely on experimental results, not on understanding what the Standard says about it.