Namespaces
Variants
Actions

Talk:cpp/language/direct initialization

From cppreference.com

The notes say:

Direct-initialization is more permissive than copy-initialization: copy-initialization only considers non-explicit constructors and non-explicit user-defined conversion functions, while direct-initialization considers all constructors and all user-defined conversion functions.

However this is not true for brace initialization (2.) which considers all constructors, but considers NO user-defined conversion functions (not even non-explicit ones), because it's actually list-initialization. Maybe this should be made more clear?

PS: I would sign up, but the site doesn't have working SSL...

Hannes 160.45.111.134 03:26, 15 May 2017 (PDT)

list-init with a single argument falls through to direct/copy init per dcl.init.list/3.8. Our page on cpp/language/list_initialization adds a note to 3.8 that says "(if T is not a class type)" because 3.6 said "if T is a class type", but it looks like compilers treat classes the same way (demo with conversion to std::string) --Cubbi (talk) 06:43, 15 May 2017 (PDT)
Class types uses 3.6 and never hit 3.8. T. Canens (talk) 11:34, 15 May 2017 (PDT)
right, that's what I'm reading too (wonder what makes that demo compile though). Updating this page to limit the use of curly braces to 3.8. --Cubbi (talk) 12:40, 15 May 2017 (PDT)
That is CWG 1758, resolved by 1467, then backed out by 2137. That issue needs to be reopened. Also, list-init has enough corner cases (e.g., 3.1 for aggregates, 3.8 & 3.9 for references) that I'm not sure it's worth the trouble trying to slice out the small subset of it falling to plain direct-init and cover it here. T. Canens (talk) 12:56, 15 May 2017 (PDT)
Hmm, no, this is even more messed up. 2137 doesn't affect this case (there's no derivation relationship). If what is now 3.8 had been moved upwards then that would resolve 1758, but I'm not currently seeing what makes the example work. T. Canens (talk) 13:03, 15 May 2017 (PDT)
I am surprised to see your demo build, mine did not: https://godbolt.org/g/TlpSpf Maybe differences because my types are aggregates? Also clang seems to want to use the user defined conversion operator, but doesn't. Hannes 160.45.111.134 02:37, 18 May 2017 (PDT)
Indeed, it depends on whether the type target type is aggregate or not, how inconsistent: https://godbolt.org/g/6IhJlV I am not sure how 3.* are applied. Does it perform 3.1, because it takes action "eagerly", or should it continue to 3.8, because 3.1 fails? In the latter case this would be an implementation issue, in the former case I would consider it a language issue, because this kind of behaviour is not expected. What do you think? -- Hannes 160.45.111.134 05:09, 18 May 2017 (PDT)
I started a thread on <[email protected]>, let's see what comes of it. -- Hannes 160.45.111.134 07:05, 18 May 2017 (PDT)

[edit] Direct init with no arguments

I noticed that std::optional::emplace "direct initialises" from its argument list, meaning that code such as std::optional<int> o; o.emplace(); will perform "direct initialisation" with an empty argument list, which this page currently provides no semantics about (and I think the standard is extremely vague on the issue if it says anything at all). I was thinking of removing the "nonempty" from "initialization with a nonempty parenthesized list of expressions", and making up that direct init with no arguments defers to value init. --Ybab321 (talk) 10:11, 16 November 2021 (PST)

that's a good point. We should be clearer in separating the syntax from the semantics; direct-init with an empty list (syntax) performs value-init (semantics). As far as the standard goes,
so I agree, but how to make it easy to follow? --Cubbi (talk) 13:44, 16 November 2021 (PST)
I've never before considered direct init to be a syntax thing rather than a semantic thing. I'll have to have a few rereads of the initialisation sections of the standard. As it stands, I don't think the current cppreference presentation is particularly unclear, think mending this page to talk about the no-arg case is probably good enough --Ybab321 (talk) 03:40, 18 November 2021 (PST)