User talk:Cubbi



std::map page

I started a discussion here too:

ERCaGuy (Gabriel Staples) (talk) 20:32, 25 January 2022 (PST)

Using-declaration page

Hi Cubbi,

On this page:

I really liked this version:

And you removed nearly all of the comments and turned it back into this version, which is significantly different:

What comments do you think we can or should put back to make the important subtleties of the using usage more clear?

In the example code, using B::f is totally useless and does absolutely nothing since the override of that virtual function would happen without it, and using B::h is totally useless and does nothing because the function definition of void h(int) then hides it, but (and this is really important) using B::g is absolutely necessary assuming the desired behavior is to keep void g(char) exposed from the parent function instead of having void g(int) from the child function hide it, thereby causing implicit casting to int if you pass a char to the child function. This is really tricky C++ behavior going on there that is begging for an explanation to even advanced users.

Comment out the three using usages I mention and you'll see only one of them does anything at all. So, what do you think we can do about this? Why not put some of those clarifying comments back in?

I've added this to the community discussion page too because I'm not sure where it's best to put this discussion, and it might be worth getting more feedback:

ERCaGuy (Gabriel Staples) (talk) 20:16, 25 January 2022 (PST)

Links to algorithms

Hi Cubbi,

I was wondering what you would think about adding external links to the algorithms implemented here for the "Possible implementation" section of each of algorithm.h's algorithms.

For instance, for the reverse algorithm we could add this link.

Best wishes,

Mgkrupa (talk) 09:58, 24 May 2019 (PDT)

I think it's actually a good idea to link to actual open-source implementations: we often look at them anyway when writing up or editing these pages. I'd use github for accessibility: for std::reverse, open-source implementations are libstdc++ and libc++ --Cubbi (talk) 11:42, 24 May 2019 (PDT)
Okay, I've added it to reverse algorithm. Now it remains to do the same for all the other algorithms. Is the format of the statement that I added to that page a good template for all the other pages? Mgkrupa (talk) 10:56, 25 May 2019 (PDT)


Hi! Welcome to the wiki. Your contributions look awesome:) Just one note: could we have only one example per page? It can quickly become a mess, especially if these examples demonstrate more or less the same feature used in the similar way.P12 14:29, 17 August 2011 (PDT)

No problem, I felt that the return value of std::for_each deserved a special mention since so few people even know it exists, but it's true that for the most part that example was a duplicate. I don't mind it gone or anything -- I just put it together on the spot. Also, nice to know I can use range for loops here! --Cubbi 14:41, 17 August 2011 (PDT)
Well, any feature in C++11 can be used, provided that the examples become simpler. After all, it's not the for loop that is being demonstrated, but the particular function, so there should be as little auxiliary code as possible.P12 14:53, 17 August 2011 (PDT)
Incidentally, why do so many examples here use std::endl where '\n' is implied? It makes it look unprofessional, as if the next line is going to be system("pause") --Cubbi 19:43, 17 August 2011 (PDT)
Did you mean that there's no reason to use std::endl as '\n' is a shorter alternative, or that there's no reason to output newline at the end of the program? The former choice actually has no strong rationale behind, just I felt that std::cout is better for the examples. As for the second, most examples would be run only in interactive mode and most probably not edited in any way, so the newline helps produce clear output. Compare:
p12@p12-laptop:~$ ./a.out 


p12@p12-laptop:~$ ./a.out 

P12 01:25, 18 August 2011 (PDT)

I mean that << std::endl is premature pessimization: it is, by definition, equivalent to << '\n' << std::flush and flush is only needed before system("pause") and in some other multiprocessing/multithreading situations or when debugging a program that segfaults (in which case always-flushed cerr works better anyway). Stroustrup's "hello world" uses \n in "The C++ Programming Language". Also, recent discussion on SO and a not so recent one --Cubbi 06:53, 18 August 2011 (PDT)
Well, I wasn't aware of that. Let's dump std::endl then. I'll instruct my bot account to search/replace every occurrence of std::endl with '\n', except where std::endl is indeed intended.P12 07:43, 18 August 2011 (PDT)

Lambda / Example

Hi! Good point on the std::function usage being already promised. //

Nitpick: isn't it better to say "stored" instead of "captured" in "captured in std::function"?

Clarification: shouldn't we at least say that there's a difference between these two cases? Note that std::function in this case can introduce severe inefficiencies (regardless on whether it is common or not, this makes it a bad practice, IMHO).

Compare the results of the following benchmark:

Further references:

// Edit: if we do decide that keeping it is a good idea (I'm not convinced), I think <functional> header needs to go back in, too.

// Request for clarification: just to make sure I'm not breaking any rules, is it better to discuss issues like this here or at the page-specific discussion section? // which would be

Note I'm not trying to be pedantic, my thinking is simply that we should strive to provide "the best practices" code in the examples whenever possible (unlike that certain other C++ reference...) and it seems to be possible in this case.

Md 13:14, 1 May 2013 (PDT)

You're right about the header of course (I tested with gcc and just pasted it as-is), and yes, discussion of language/lambda is better on the language/lambda's talk page -- that's where visitors would look for comments and opinions such as these. std::function of course has the potential for overhead, but I think the best place to expand on that is std::function's main page, in a ===Notes=== section, where implementation details and caveats would be appropriate (e.g. compare to std::shared_ptr's Notes). Wrapping a lambda in a function is not justified in the example, but it is justified in enough real-life use cases (to pass to a non-template function, to apply std::not1, etc) --Cubbi 14:13, 1 May 2013 (PDT)

"must return"?

Regarding the comment on this and other diffs. int main() does not require a return statement, Not in C (since 1999), not in C++ (ever). Stroustrup's "hello world", again, has no return statement. But if its a good idea to have all code here include that statement, Help:Manual of style needs to be updated. --Cubbi 14:20, 23 August 2011 (PDT)

Oh great. I must have wasted a lot of return statements. If they are not mandatory, we can omit them. BTW, could you start discussions like this in my talk, so that I get a notification?P12 02:09, 24 August 2011 (PDT)
Okay. BTW, the reference for it: 3.6.1[basic.start.main]/5 (same in C++03 and C++11) "If control reaches the end of main without encountering a return statement, the effect is that of executing return 0;" --Cubbi 03:17, 24 August 2011 (PDT)

using std::less in std::lower_bound

Is this edit correct? What if the argument types to std::less are not convertible to each other, yet have a comparison operator defined? Is there's a solution to that problem?P12 14:43, 24 August 2011 (PDT)

You're right, that less is missing the second type. In LLVM's libc++ library, the first form of std::lower_bound is defined exactly this way:

template <class _ForwardIterator, class _Tp>
lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value)
    return _VSTD::lower_bound(__first, __last, __value,
                             __less<typename iterator_traits<_ForwardIterator>::value_type, _Tp>());
I'll edit accordingly. --Cubbi 15:15, 24 August 2011 (PDT)

Oh, wait, standard less only takes one argument.. --Cubbi 15:18, 24 August 2011 (PDT)
So it looks like we'll have to duplicate this one, or come up with a two-argument functor or lambda just for the sake of that one example equivalent function. --Cubbi 15:24, 24 August 2011 (PDT)
So let's keep the duplicate then. Unrelatedly, I think there's no need to have exact permutation, sort and other long algorithms outlined in the equivalent function section. They're too complex for anyone to grasp quickly, so it might be a better idea just to leave a 'black box' instead.P12 15:38, 24 August 2011 (PDT)
Even std::random_shuffle can be hard to grasp if you're unfamiliar with Fisher-Yates-Knuth algorithm. I think implementations of the permutations are rather simple for what they do, and to me it was educational to learn how the three permutation functions are implemented (identically in both libraries I looked at, too). I agree about sorts, stable_partition, and anything that does something different "if additional memory is available" - those are complex and they are implemented differently in different libraries. If I were to cut one, I'd cut std::minmax_element, it's too complex for what it does. But there's so much work to be done on this wiki still, it feels like a minor thing anyway. --Cubbi 18:57, 24 August 2011 (PDT)
Ok, after coming across the page of std::is_permutation I reversed my opinion. The algorithm is quite clear if there are some comments about how the code works. Maybe all we need is a very short explanation above the code for the most complex functions? Anyway, equivalent functions, like examples, reside at the very end of the page, so they aren't really important. Since probably the only people, who will come across those sections, are the ones who're looking for additional reference, lots carefully selected information will be certainly beneficial.P12 13:03, 25 August 2011 (PDT)

wide character strings

Wide character strings are not the same as multibyte character strings. There are actually three character string types:

  • character / byte / narrow-character null-terminater string, e.g. ASCII-8
  • multibyte null-terminated string, e.g. UTF-8
  • wide / wide-character null-terminated string, e.g. UCS, UTF-16, etc.

Multibyte character string is like an 'extension' to regular byte character strings, since a multibyte character string is always a valid byte character string, so it is can be processed by all functions at cpp/string/byte, but not the functions at cpp/string/wide.

Anyways, this is a quite complex subject, it needs to be explained better in the article lead sections.P12 15:49, 2 September 2011 (PDT)

You're right, the definition of NTMBS is not suitable for string/wide at all. An NTMBS is more like what a std::wstring_convert().to_bytes() would produce from a wchar_t[]/wstring. But yes, it would be nice to detail the differences between C++'s four character types and the data that can be stored in them. --Cubbi 16:44, 3 September 2011 (PDT)

Template:ddcl list namespace

Hi. My edits adding {{ddcl list namespace}} were a mistake, since the namespace can easily be deduced from the page title as is done e.g. std::this_thread::sleep_for. I'll revert them. Sorry for inconveniences.P12 13:34, 4 October 2011 (PDT)

Ah, okay, sorry about running along with it. --Cubbi 13:36, 4 October 2011 (PDT)

{{param none}}, {{return none}}, {{throw none}}

Hi. I decided that {{param none}}, {{return none}}, {{throw none}} serve no purpose as the current style is adequate and probably won't change in the future. I'll replace these templates with the text they resulted in - (none). I hope this will make editing easier. P12 13:03, 11 October 2011 (PDT)

Re. mem=

Hi. I've fixed the inconvenience caused by the necessity to use mem parameter in the dcl list mem * templates. Now if a dcl list mem * template is placed in a page which is not a sibling or parent of the target page the template links to, member of std:: is added automatically. E.g.

Template:cpp/memory/shared ptr/dcl list get

So the mem= parameter is not needed anymore. P12 13:23, 19 January 2012 (PST)

Cool, thanks. I wish i could understand that code you just changed! --Cubbi 13:27, 19 January 2012 (PST)
The idea is not very complicated, the syntax is. The dcl list * templates always get a path to function/class page they represent. When used, the template now checks whether the target page and the page they are used in have common ancestor. If yes, everything is as in the past. Otherwise, the template acquires and displays the name of the parent class of the target page. Here it knows that if we have a/b/parent/member_function, then there's always Template:a/b/parent/title and if the title template gets #MAGICTITLESTRING#, then it just yields in the part of the title which would be displayed in the smaller font. So for e.g. {{cpp/container/vector/title|#MAGICTITLESTRING#}} we get std::vector<T,Allocator> which is what we want. P12 16:50, 19 January 2012 (PST)

sorry for being such a pain

I'll try to avoid making radical changes without searching first. I need to actually look more into the standard before modifying things. >.< --- Undeterminant 12:29, 11 February 2012 (PST)

adding a function or two is nothing radical. It's a wiki. If someone thinks it can be improved, they will. --Cubbi 12:32, 11 February 2012 (PST)

operator++ with or without (int) overload in links

Hey, thanks for all the work on the iterators. I only wondered why you put the (int) overloads into the links for the ++ operators, for example

advances the iterator
(public member function of std::reverse_iterator<Iter>)

Usually the overloads are not specified in the links (e.g. constructors, operator[]).

Would you be ok, if I started changing this to the shorter version below?

advances the iterator
(public member function of std::reverse_iterator<Iter>)

Or are there some caveats that I missed?

Tobi 03:23, 3 April 2012 (PDT)

They are not overloads, they are post-increments. Post-increment and pre-increment are fairly different (but not different enough to have separate pages).. On second thought, I suppose it does clutter the link unnecessarily. Ultimately, style decisions are up to P12, I'm just an editor. --Cubbi 05:43, 3 April 2012 (PDT)

Russian translation

Hi. Could you take a look at the Russian wiki and translate the most frequently used templates if you have time? Most of the templates are only few words or sentences, so the translation would need at most several tens of minutes. I then would import the rest of the English content and add some advertising at the Dokuwiki version too gather attention of other editors. Thanks! -- P12 09:37, 25 April 2012 (PDT)

I started, but can't promise to be fast. --Cubbi 10:40, 26 April 2012 (PDT)
Nevermind, I think Krtkr won't return anytime soon. I'll just import the current content of Dokuwiki. -- P12 10:20, 30 April 2012 (PDT)

Svg conversion of the File:Streambuf.png

Hi. I've created an explanatory image for std::basic_streambuf based on your initial draft. Your image was really helpful, thanks! P12 18:02, 16 May 2013 (PDT)

Alas, poor dynarray

...we hardly knew ye. I wonder if it makes sense to leave the std::dynarray and std::optional content in place (with the hope that at some point they'll return) and just attempt to remove other links to/uses of them? --Nate (talk) 17:06, 30 September 2013 (PDT)

I vote for leaving the content in place. There are lots of links to these pages over the internet already and people who come through them won't like 404s being served. We could even replace the (since C++14) tags with something like (removed from the standard draft). --P12 18:28, 30 September 2013 (PDT)
It's getting moved to a separate TS (along with some other things that got dropped from the WP), so it's still going to exist and worked on, just not getting released in C++14.. Until there's a new draft to reference, I'd keep it, maybe with a note that it was voted out as far as we know. (here's relevant StackOverflow chat session where I picked that up - scroll up for more notes about Chicago) --Cubbi (talk) 18:29, 30 September 2013 (PDT)
Another prooflink (from gcc library maintainer, regarding dynarray and VLA): --Cubbi (talk) 07:17, 1 October 2013 (PDT)
Any information on why optional got mothballed too? As opposed to dynarray, it doesn't look like a risky addition without implementation experience. --P12 09:03, 1 October 2013 (PDT)
Two National Bodies comments were asking for (more) relational operators for it, and there was a pre-Chicago paper about all the different approaches to that, sounds like no consensus. SO chat suggests that, too --Cubbi (talk) 09:28, 1 October 2013 (PDT)

C++14 status

Just out of curiosity, do you have any estimates how much C++14 stuff we're still missing? --P12 13:57, 10 November 2013 (PST)

I just went up the Chicago issues in libc++'s checklist today and added whatever I found missing in the library, I didn't double-check every earlier issue, but I think the library is actually complete at this point (although a few simple redlinks remain, e.g. the literals for complex numbers and some durations). Core language is certainly missing some C++14 improvements (polymorphic lambdas and return type deduction in functions, for example), but it's work in progress anyway --Cubbi (talk) 17:02, 10 November 2013 (PST)
Thanks. I guess it's time to update the news template. --P12 03:07, 11 November 2013 (PST)

Mistakenly reverted edit

Sorry for this, it was an accident :) --P12 16:52, 20 February 2014 (PST)

Must we enclose some big chapters with {{rev}} template (such as in [1])?

I realized that it is for gadget StandardRevisions and it does look nice in C++03, C++11 and C++14 mode. But if someone view the page in the default mode, I'm afraid it would be a little difficult for him to find the (since C++14) sign and it would be confusing. --D41D8CD98F (talk) 20:05, 6 June 2014 (PDT)

actually that part could use both the (C++14) right on the heading and the rev box for the gadget. Perhaps you can bring it as a case study to Talk::Main_Page to revive the old revbox discussion/brainstorming. Good work by the way. --Cubbi (talk) 21:00, 6 June 2014 (PDT)
Thank you. The link is really informative. I've added a section in Talk:Main Page to discuss this issue.--D41D8CD98F (talk) 00:30, 7 June 2014 (PDT)

Contributions to the standard revisions gadget


I'd like to commit this change to the cppreference-doc Github repo. What name and email should I use to attribute your contributions? Cheers. --P12 15:16, 18 November 2014 (PST)

It's about time I started using this github thing myself. --Cubbi (talk) 19:39, 18 November 2014 (PST)

Automatically linking _t aliases

Right now, std::add_pointer<int> automatically links std::add_pointer, but std::add_pointer_t<int> doesn't. I believe this takes an admin to fix :) T. Canens (talk) 14:13, 7 July 2015 (PDT)

correct, if no one else from admins does that first, I'll go over the _ts from type_traits. --Cubbi (talk) 14:21, 7 July 2015 (PDT)

Conjunction in odr-use

Hi, I've made an edit that changes the meaning of some of your text:

This arose at where the asker was (rightly) concerned about a contradiction between the Standard, SO and cppreference. I think my change makes it clearer and more correct but thought I should give you a heads up in case you want to make further changes.

I wonder whether we should further expand on the "potential results" business - it's come a long way from the original meaning of the two legs of a ternary, but perhaps some mention of that evolution might help readers understand what the text in the Standard is trying to accomplish. (talk) 04:31, 13 July 2015 (PDT)

Thanks for editing! Yes, it would be very helpful to drop in a note explaining the intent: I feel a little bit defeated whenever standardese appears here without any sort of informal summary or background info (ODR here begins with an informal summary) --Cubbi (talk) 07:17, 14 July 2015 (PDT)

Updates to indexes

Hi. I've synchronized the new API you've added to the search indices with the XML files in the cppreference git repo and only now noticed that you've likely edited the XML too instead of some manual way. Could you please do a PR to the github repo so that the effort is not duplicated? Many thanks for all the improvements! Cheers. --P12 18:56, 7 August 2015 (PDT)

it was actually manual (hence "fingers crossed" in my edit summary!), well, vim-assisted --Cubbi (talk) 22:17, 8 August 2015 (PDT)

Member access operators

Could you please stop canceling all my work on this page? You can correct my edits, but please don't cancel everything without reading my improvements, especially when you bring back a version that is less consistent.

1. You state that the subscript operator is not only for arrays. No problem, but then please be consistent and remove the word "array" in the summary table. Because the current situation is "array subscript" in the table, "Built-in subscript operator" in the title of the section and "Array subscript operator provides access to the elements in the internal array" in the explanation. What a mess for the reader!

2. I corrected the prototypes of the summary table from this source: [2] so please don't revert my edit or improve it from a better source. Plus I added missing semi-colons in the last prototypes of the tables and you reverted it, this is counter-productive.

3. In the 1st paragraphs of the sections "Built-in member operators" and "Built-in pointer-to-member access operators", the description of the operands are not in the same order, that's why I changed it (1st—or left—operand THEN 2nd—or right—operand for BOTH sections) but you reverted my changes again. Please.

4. In these same two sections, I used the same symbols "A" and "B" and you are persisting to keep "expr" and "member" in the 1st section and "E1" and "E2" in the 2nd section. I have nothing against these symbols, but again be consistent in your notations and use the same identifiers for the two sections (either textual identifiers or symbolic identifiers, but not both!)

5. I insist: please be consistent!

6. By the way: I appreciate your other corrections on the other pages that I edited.

Maggyero (talk) 13:11, 26 August 2015 (PDT).

Yes, I was a little jumpy after the mess at value_categories and various earlier problems with your edits, sorry about that. This edit ([3]) was in fact mostly viable and I restored much of it after giving it some thought.
1 The summary table and the "explanation" blurb under it shouldn't say array, that's a good point. They haven't received much attention over all.
2 Wikipedia's C and C++ pages are bad sources. Cppreference:FAQ here explains where to get actual language specs.
3 The loss of the link to id-expressions and of the note on evaluation of the left operand were the main triggers for the revert. I did restore your general wording later after bringing back that lost content.
4 the right-hand operand of the member access expression is a very special beast, it is nothing at all like the operands of all over operators used on this page: the other operands are expressions that can perform arbitrary computations, but this operand is just the name of a member. I couldn't find a clear single-letter way to describe that differently from how the other expressions are described, so I used words. Perhaps a better approach would have been to use syntax parameter templates (expression . member-id), but that ended up unappealing too. The grammar still classifies the second operand as an expression (id-expression) and designates "E2" when described in the standard, so I restored your E2. --Cubbi (talk) 13:36, 26 August 2015 (PDT)
Thank you for the restore and the information, especially the FAQ advice. I have just downloaded the last Working Draft of C++ 14 so now I have THE reference and I will be able to make fewer errors :).
Maggyero (talk) 03:31, 27 August 2015 (PDT).
Good, the other extreme to avoid is copying too much standardese since it is often incomprehensible (try reading through 14.7.3[temp.expl.spec]/7!). See the poll I started at Talk:cpp/language/operator_member_access#Naming_bikeshed (I don't care that much about address-of's name to be honest, but saying "address-of" helps connect it mentally with its better-behaved cousin std::addressof) --Cubbi (talk) 03:39, 27 August 2015 (PDT)
Hi Cubbi! I have just answered on my talk page about your last comments.
Maggyero (talk) 16:47, 18 September 2015 (PDT)

Value categories

Hi Cubbi. My edit on the Value categories page was only about member access operators in order to make the statements match with the ones that are on the Member access operators page. I also uniformized the wording (the word "first operand" "second operand" was used everywhere in the page except in member access operators) and only changed the order of some item so that everything is symmetric for the 3 primary categories. Then I replaced the vague "some ternary conditional expressions" with the exact cases (it holds in a very short sentence so there is no need to remove the details) like for all the other operators. Finally I added a forgotten prvalue in the list: the one that is used for the pseudo destructor call. So except for this new prvalue I didn't really add or change anything apart for the style, it's just more consistent so easier to read. Should I split this edit in several small edits like they are in this step-by-step explanation?
Maggyero (talk) 18:02, 19 September 2015 (PDT).

It was a complex disruprive edit made to a sensitive page with no prior discussion. Changes to the conditional were wrong (it's "some" for a reason), changes to member access removed content. Granted with all these non-technical edits from last month, it's becoming increasingly hard to even understand what those sections is talking about, it should really go back to what it said before august. Pseudo-destructor is covered by the PMFC section and does not belong with regular rvalues. I don't agree with the reordering either, but it wasn't a technical error. --Cubbi (talk) 19:38, 19 September 2015 (PDT)
Just to elaborate on the conditional part, since I'm the guy who introduced the "some ternary conditional expressions" wording: a correct (I think) description of when an conditional expression is an lvalue is
  1. if one of the second and third operands is a (possibly parenthesized) throw expression, and the other one is an lvalue; or
  2. if the second and third operands are lvalues of the same type; or
  3. if the second and third operands are lvalues of the same type except for cv-qualification, and one is more cv-qualified than the other; or
  4. if the second and third operands have different types, at least one of which has a class type, and one of the second and third operands (call it X) is an lvalue of type T, and the other operand (call it Y) can be unambiguously converted to the type T&, subject to the constraint that the reference must bind directly to an lvalue, and Y cannot be converted to match X.
And I even cheated a little above by not describing what "Y cannot be converted to match X" actually means. I think you can see why I went with the vague version instead.

While we are here, I'm not really a big fan of the current wording at cpp/language/operator_other#Conditional_operator. The previous version was inaccurate in a number of ways, so I rewrote it by tracking [expr.cond] pretty much exactly, and the new version is probably correct, but it's also pretty dense and hard to understand. If anyone knows a way to simplify it without sacrificing correctness, I'm all ears. T. Canens (talk) 00:55, 20 September 2015 (PDT)

1. Since the standard states, § 5.16. "Conditional operator", alinea 4, 5:
"If the second and third operands are glvalues of the same value category and have the same type, the result is of that type and value category and it is a bit-field if the second or the third operand is a bit-field, or if both are bit-fields. Otherwise, the result is a prvalue."
I thought it was a sum up for all cases (especially for the void cases listed in alineas 2 and 3), but apparently not (so I find the standard a little messy about the value categories here). So OK Cubbi an T. Canens, no problem for keeping the vague "some ternary conditional operator expressions".
2. OK Cubbi, if it does not really belong to "real" prvalues I will remove the special kind of prvalue I introduced.
3. OK Cubbi, for the moment I will keep the order as it was because it makes the edit very hard to read for everyone with the comparison tool, and we will come back to it later.
4. Not OK Cubbi about the "changes to member access removed content". I have only replaced the "every member access operators except" by "member access operators where" like it is in all the other items (consistency), but if you check with care I have not forgotten any case.
Maggyero (talk) 03:33, 20 September 2015 (PDT).
You lost the value categories of a->b and a->*b by writing "using operator ." and "using operator .*" in the wrong place. Also, you added text where this page really needs a lot less text than what it has today: it is not a page about member access or about ?:, it shouldn't duplicate technical details covered on the pages it links to. --Cubbi (talk) 06:13, 20 September 2015 (PDT)
You say that I lost the value categories of a->b and a->*b by writing "using operator ." and "using operator .*" in the wrong place, that is to say the value categories of the first operand, but a->b and a->*b are automatically converted to (*a).b and (*a).*b and in the Member access operators page the value categories are always given for E1.E2 and E1.*E2, that is for the first operand E1 = (*a) and not for E1 = a, so that we don't care about the value category of E1 = a and therefore about the operators a->b and a->*b. For this reason we have to write "using operator ." and "using operator .*" everywhere the first operand is mentioned. With the old wording of the page Value categories, there was no need to precise "using operator ." and "using operator .*" for listing the lvalue cases because they were listed negatively ("everything except…") and these exceptions do not depend on the first operand. But when listed positively (nothing except…) some lvalue cases depend on the first operand so it has to be explicitly said that this first operand is the one of the operators . and .* (after possible conversion from -> and ->*) and not of the operators -> and ->*. And by the way, the old wording (the current one actually, since you undid me) did have an error:
"a built-in pointer-to-member access operator expression where the first operand is an lvalue and the second operand is a data member;"
is a wrong statement since in the Member access operators page which has the same statement it is explicitly written that the operands that we are talking about are "In the expression E1.*E2:" (so after possible conversion from a->*b). So actually my last edit did correct one error but didn't introduce new ones.
Maggyero (talk) 14:21, 20 September 2015 (PDT).
There is no "automatic conversion" here, you are mixing up unrelated concepts. Yes, the word "pointer" is missing, that would have been an acceptable edit. --Cubbi (talk) 19:11, 20 September 2015 (PDT)
Could you elaborate on this because I am not sure that I follow you here. To my understanding, since the standard explicitly states, § 5.2.5. "Class member access", alinea 2.:
"The expression E1->E2 is converted to the equivalent form (*(E1)).E2; the remainder of 5.2.5 will address only the first option (dot). Note that (*(E1)) is an lvalue."
that means that the second option (arrow) is addressed the same way, considering as the object expression (*(E1)) instead of E1. So for instance the statement given in the standard for the first option (dot, that is E1.E2), § 5.2.5. "Class member access", alinea 4.2.:
"If E1 is an lvalue, then E1.E2 is an lvalue; otherwise E1.E2 is an xvalue."
would become for the second option (arrow, that is E1->E2 = (*(E1)).E2):
"If (*(E1)) is an lvalue (which is always the case), then E1->E2 is an lvalue; otherwise (which is never the case) E1->E2 is an xvalue."
But according to you, the statement given for the first option would remain the same for the second option (arrow, that is E1->E2 = (*(E1)).E2):
"If E1 is an lvalue, then E1->E2 is an lvalue; otherwise E1->E2 is an xvalue."
Did I understand you correctly? Do you confirm that my understanding of what is happening for the second option (arrow, that is E1->E2) was wrong?
Maggyero (talk) 01:34, 21 September 2015 (PDT).
I think you're off-track. The built-in a->b can be lvalue or prvalue, depending on what b is (e.g. memeber variable vs. member enumerator). The edit I reverted removed a->b from the value categories page (and I admit it's badly represented there, hidden in semi-standardese "member access operator expression". We'll look at it after cppcon). --Cubbi (talk) 15:16, 21 September 2015 (PDT)
Alright. However I think you have not read my last answer correctly (or maybe I was not clear enough). I have never said that a->b cannot be a prvalue. The statement that I quoted from the standard was in the context of E2 being a non-static data member of non-reference type of course. So maybe I should reformulate my question better: when E2 is a non-static data member of non reference-type, what is the value category of E1->E2? The standard only address this case for E1.E2, stating:
"If E1 is an lvalue, then E1.E2 is an lvalue; otherwise E1.E2 is an xvalue."
So in other words, what this sentence would become for E1->E2?
  • This?
"If E1 is an lvalue, then E1->E2 is an lvalue; otherwise E1->E2 is an xvalue."
  • Or that?
"If (*(E1)) is an lvalue, then E1->E2 is an lvalue; otherwise E1->E2 is an xvalue."
If it would become the latter, since (*(E1)) is always an lvalue anyway, then E1->E2 would always be an lvalue (when E2 is a non-static data member of non-reference type).
— Maggyero (talk) 01:54, 22 September 2015 (PDT).

"why 2111 was strike through in TC's list?"

Because I started the <s> at the wrong place :P. Also, when you have time,meow_v should be added to the autolinker thing :) T. Canens (talk) 09:16, 27 October 2015 (PDT)


Nice to see I don't have to pester you about insert_or_assign/try_emplace :) For the LF TS, we are missing the experimental:: version of conjunction/disjunction/negation (and _v), randint, reseed and shuffle :). T. Canens (talk) 15:06, 20 November 2015 (PST)

autolinker seems broken?

I don't see a link with, e.g., std::function. T. Canens (talk) 15:44, 4 December 2015 (PST)

maybe my hacky edits broke it.. P12 may be in the better position to figure it out. --Cubbi (talk) 17:40, 4 December 2015 (PST)
Well, I'm no expert, but the final portion of this diff seems suspect:
  "target": "cpp/utility/variadic/va_start"}]}
+ {"string": "__has_include",
+ "target": "cpp/preprocessor/include"},

Note the ]} at the end of the va_start line. T. Canens (talk) 00:03, 5 December 2015 (PST)

You were right, looks like removing those two lines fixed std::function --Cubbi (talk) 10:07, 8 December 2015 (PST)


Hi Cubbi! It's been a while. What is the type of a constructor call, such as int()? I know it's an rvalue, but is it a prvalue or an xvalue? (It doesn't have a return type so I can't decide.) — Maggyero (talk) 15:59, 15 December 2015 (PST).

expr.type.conv says it's prvalue, regardless of whether T is primitive or object type. Slightly surprising but I doubt it changes anything much. (talk) 12:15, 17 January 2016 (PST)

string_view remove_prefix example

Hi, your example for string_view::remove_prefix has undefined behavior if find_first_not_of returns npos i.e. if the string is entirely blank (including if it is empty). The result will be to extend the start of the view backward one byte, which may not be visible if the previous byte is zero. I'm particularly worried that people might use this as the canonical way to left trim a string view. Do you think it would be worth it to protect the argument with std::max against v.size()? (talk) 12:32, 17 January 2016 (PST) PS. Looks like remove_suffix has the same issue.

sure, it sounds like a simple way to make the example more helpful, thanks for spotting! --Cubbi (talk) 12:43, 17 January 2016 (PST)

Copy elision

Great addition to my edit for the paragraph on move priority when copy elision cannot be performed, the standard was very hard to render in simple terms on this matter, thanks. — Maggyero (talk) 13:00, 20 January 2016 (PST).


You say "an identifier is not an expression (id-expression is)" but you write in the article "The expression consisting of just the identifier returns" and "together with identifiers they are known as id-expressions" and the standard explicitly states the following categories:

  • id-expression
    • unqualified-id
      • identifier
      • operator-function-id
      • conversion-function-id
      • literal-operator-id
      • ~ class-name
      • ~ decltype-specifier
      • template-id
    • qualified-id

An identifier is an unqualified-id, which is an id-expression, which is an expression, so an identifier is an expression.

And the current version of the article is a mess:

  • inconsistent naming: (operator function, operator in function notation), (template identifier, template-id);
  • inconsistent examples and styles: (MyTemplate<int>, name<arg, arg>);
  • ambiguous sentences: "Besides simple names of objects and functions, the following language constructs can be used in expressions in the same role (together with identifiers they are known as id-expressions)".

"that is not a complete list by far": alright on this point. — Maggyero (talk) 13:00, 20 January 2016 (PST).

the grammar does not tell you what something is, it has nothing to do with semantics. It says that any sequence of digits and non-digits beginning with a non-digit is accepted by the parser where the grammar production expression is expected.
for "inconsistent naming: (operator function, operator in function notation),", yes, it is an inconsistency. If you think it's worth correcting that, make an edit that does so with the summary "renamed "operator function" to "operator in function notation" for consistency with the section on names" instead of rewriting the entire page in completely new terms with "wording" as a summary.
Regarding "template id" and "template identifier", template-id is bad because it's a BNF term and "template identifier" is bad because it's incorrect (it's not an identifier). Perhaps it can say "template name followed by its argument list". --Cubbi (talk) 13:54, 20 January 2016 (PST)
Alright, therefore "qualified identifier" is bad too since it is not restricted to identifiers (overloaded operator name, user-defined conversion function, etc.). So in the article I have just changed "qualified identifiers" to "qualified id-expressions" to follow this logic. And I have also moved the section to subsection of "In expressions". — Maggyero (talk) 01:45, 22 January 2016 (PST).
Don't change headings unless you're prepared to fix all the links that lead to it (I fixed it once for you, when you renamed compound statement) --Cubbi (talk) 05:56, 22 January 2016 (PST)


Is it a concept? I don't see any requirements on it (besides, of course, that return searcher(first, last).first; must work). T. Canens (talk) 14:17, 17 March 2016 (PDT)

hm, you're right, there is no named requirements section for it, even though "class Searcher" looks deceptively like one of the named library concepts and user-provided searchers are apparently expected (every standard searcher is CopyConstructible, but the one required by std::search doesn't have to be). Perhaps it would make sense to make a little page saying that searcher(first, last).first must work and whatever that implies. I wouldn't be surprised if when Ranges TS gets updated to C++17, they would add something more restrictive. --Cubbi (talk) 14:28, 17 March 2016 (PDT)

Type Traits

Hi, it looks like you wrote most of the type traits docs. Most of the pages I looked at have the text "provides the member constant value equal true. For any other type, value is false." That isn't correct English, specifically "value equal true" is not grammatically correct. One alternative would be "provides the member constant value, equal to true" instead.

Also, the way the sentence is phrased is somewhat ambiguous. One possible reading is that if the condition is true, it provides the member 'value'. But (for most traits) the member is always provided, not only when the condition is true. One option would be to separate the part about providing the member, so that it isn't implied to be conditional on the property being tested.

The 'is_union' page avoids both these problems (although the punctuation was slightly incorrect there, so I've just fixed that). Jwakely (talk) 10:27, 15 April 2016 (PDT)

Indeed, looks like I am to blame for cloning that sentence across most of those pages in october 2011, and I agree that it doesn't look good. Hopefully the "Member Constants" block just below those ("value[static] true if T is XYZ, false otherwise") helps until they get reworded (I'll probably make it a wiki template so that the wording is all in one place). --Cubbi (talk) 10:40, 15 April 2016 (PDT)

malloc &c. thread safety

Aren't they covered by [] even before the C11 sync? T. Canens (talk) 14:26, 24 June 2016 (PDT)

General thread-safety probably yes (has it been argued by language-lawyers somewhere?). In which case that first sentence needs to be retagged C++11 rather than C++17. I am not sure general thread-safety implies synchronized-with and the total order from C11 spec, though. --Cubbi (talk) 14:41, 24 June 2016 (PDT)
Ah, both regular thread safety and the single total order was explicitly called out in[new.delete.dataraces] all this time. in C++11 --Cubbi (talk) 14:46, 24 June 2016 (PDT)

std::iterator becoming deprecated in C++17

Would it be relevant to add a suggested implementation for the example in cpp/iterator/iterator that doesn't use std::iterator (probably with the fixes you've made to this example...). The question regarding the substitute is addressed here in SO. I think putting the same example without the inheritance from std::iterator can answer the question of "what is the substitute for std::iterator in C++17" (I think the answer is: "there is none") and be a good preparation for anyone who is "worried" about this change. Amirk (talk) 07:30, 29 June 2016 (PDT)

use boost.iterator or "provide your own member typedefs" could be a useful note (in a "Notes" section), possibly referencing the concrete iterators from cpp/iterator which already do that, such as std::reverse_iterator. Just don't call them "traits", they are a different facility. --Cubbi (talk) 08:37, 29 June 2016 (PDT)

"simplified" value categories

I think P0135 and what we had before that are two very different approaches to value categories, and I'm a little worried that having them both mixed together will be more confusing than just having either one. I don't have a good suggestion right now, though. T. Canens (talk) 08:43, 29 June 2016 (PDT)

I thought the same thing when I saw that proposal. The concept of rvalue evolved away from Bjarne's orthogonal axes (identity/moved-from). Perhaps the intro for the page can be broken in half like cpp/language/eval_order (I tried to cheat by putting new definition under "formally", but it really isn't the same anymore). The lists of what is l- and what is r- seem to be mostly untouched though. --Cubbi (talk) 09:08, 29 June 2016 (PDT)
or perhaps the page can be written in C++17 terms consistently and have an extended history section. --Cubbi (talk) 17:14, 29 June 2016 (PDT)
That may be better. Since the classification of actual expressions didn't change, I think dividing the page is more trouble than it's worth. T. Canens (talk) 23:08, 30 June 2016 (PDT)

Autolinker for bad_optional_access needs updating

std::bad_optional_access should go to cpp/utility/optional/bad_optional_access. It's currently pointing to cpp/utility/bad_optional_access. T. Canens (talk) 12:05, 29 June 2016 (PDT)

ok, updated. --Cubbi (talk) 12:53, 29 June 2016 (PDT)

Putting _v and _t in the dsc templates

I like the idea in principle, but it makes the marking in the right column a bit misleading, e.g.:

obtains the size of the variant's list of alternatives at compile time
(class template) (variable template)[edit]

variant_size_v isn't a class template. T. Canens (talk) 12:47, 7 July 2016 (PDT)

indeed.. might have to invent a way to pair up those tags. Or just go back to hiding helpers inside their parent entity's page.--Cubbi (talk) 12:56, 7 July 2016 (PDT)


Thank you for the edits that you made to my edits.

note as another editor pointed out, initializing/inserting init lists with repeated keys into sets/maps is underspecified: lwg2844. Meaning, it's valid, but we can't show a deterministic output from such a constructor. --Cubbi (talk) 05:49, 24 February 2017 (PST)

I hate MediaWiki sometimes

So apparently the rule is that unnamed parameters don't get whitespace trimmed but named ones do, so to pass a linebreak at the beginning to {{rev}} - which is needed for that little bullet - you have to use an unnamed parameter. Of course, = inside the parameter text would be a problem, but luckily(?) there's the magic incantation {{{|{{{1}}}}}}. Ugh.

Anyway, {{rrev|1=*a=b}} should work now and produce
  • a=b
T. Canens (talk) 15:14, 17 March 2017 (PDT)

Copying a NaN may not preserve its bit representation

As on std::numeric_limits::quiet_NaN, std::numeric_limits::signaling_NaN, and std::isnan - I think these are all yours?

> Copying a NaN may not preserve its bit representation.

> Copying a NaN may change its bit pattern.

I'm aware that copying a signaling NaN may quiet it, and that this may require a change to the payload on platforms where the NaN flag is 1 for signaling, but it's my understanding that IEEE 754 mostly-ish requires that payload (and usually sign) is preserved through function calls, which implies that it should be preserved by copy. Would it be OK to ask for clarification? Thanks! (talk) 07:27, 4 April 2017 (PDT)

the 2008 version of IEEE 754 recommends but doesn't require payload preservation "for an operation with quiet NaN inputs, other than maximum and minimum operations, if a floating-point result is to be delivered the result shall be a quiet NaN which should be one of the input NaNs" (actually the entire payload paragraph is a "should"). C echoes that when talking about math.h functions taking NaN arguments "Functions with a NaN argument return a NaN result" and under "Recommended practice", "the result should be the same as one of the NaN arguments except perhaps for the sign". Thanks for the highlight, it should actually be noted that NaNs aren't quite so scary in real life. --Cubbi (talk) 08:56, 4 April 2017 (PDT)

Those guides

I suspect that the lock_guard(lock_guard<T>) -> lock_guard<T>;-like guides were formulated before the newest rules in P0620R0. They are now useless, because they have the exact same form as the copy deduction candidate, and (in the absence of other guides) have the same priority in overload resolution. T. Canens (talk) 09:46, 12 April 2017 (PDT)

quite likely, at least I couldn't put together an example that would behave differently just now --Cubbi (talk) 09:53, 12 April 2017 (PDT)
tried to trace it.. the lock guides were added to the LWG wiki in Kona on friday 19:08, and the friday minutes mention "We need a pack expansion for scoped_lock", but nothing I could find about the other locks. --Cubbi (talk) 13:56, 12 April 2017 (PDT)
Mike Spertus indicated on std-discussion that those guides were added due to pre-P0620 rules and that he'd be working to get them removed. T. Canens (talk) 15:56, 12 April 2017 (PDT)

At least for Core issues, I wouldn't use It often points to the wiki instead (and in fact is doing it right now), and becomes completely useless for non-committee-members. T. Canens (talk) 19:33, 21 July 2017 (PDT)

huh, indeed, I didn't notice! A shorter URL would be nice, though.. --Cubbi (talk) 06:44, 22 July 2017 (PDT)


Our current description doesn't handle multidimensional arrays correctly. (The standard wording is recursive here; the placement new/construct is only ever used on std::remove_all_extents_t<T> objects.) T. Canens (talk) 09:07, 2 August 2017 (PDT)

thanks for paying attention and fixing! --Cubbi (talk) 11:05, 2 August 2017 (PDT)

constexpr too much

I saw you apply p0415r1, but constexpr is full of pages and makes dcl too long. How about writing like below? just like page operator new do?

Specialization for double
constexpr(since C++20)

Yaossg (talk) 20:46, 7 December 2017 (PST)

it is set up to look right when you switch the displayed revision to C++20 in the revision pulldown on top right: try viewing cpp/numeric/complex/operator_arith that way). I'm not happy with nodiscard on operator new, it doesn't look like the part of the declaration it is. Eventually it should either be written up as dcl rev multis, or we invent inline version tagging of individual parts of a dcl --Cubbi (talk) 06:19, 8 December 2017 (PST)
I don't think we can individually tag dcl components while we are using GeSHi to do syntax highlighting, but then we probably don't actually need the full syntax highlighting powers in dcls. If we have something like Scribunto we should be able to have much better dcls...... T. Canens (talk) 14:58, 8 December 2017 (PST)


What do you think deferring its application until after Rapperswil? I don't want to apply it and then have to rip it out for P0945. T. Canens (talk) 07:10, 17 March 2018 (PDT)

We may also want to defer the application of P0780R2 until the [...&foo=bar] vs [&] issue gets sorted out. T. Canens (talk) 19:46, 17 March 2018 (PDT)

trivial default construction and implicit object creation

Talk:cpp/language/default constructor#Objects with trivial default constructors please see my follow-up question at the bottom. --Itaj (talk) 23:13, 9 April 2018 (PDT)

std::visit example

I see you've removed the simpler std::visit example. The current visit example is insane for such a simple concept and takes an elitist approach to examples. The concepts you need to know to quickly understand std::visit's example : general template meta programming, std::false_type, variadic templates, custom type traits, std::decay, decltype, c++ type_traits, if constexpr. I'm not even sure I fully understand the "overloaded" example.

In the hopes of making simple things simple, the example should demonstrate how to use std::visit. Not write nifty template metaprogramming to show off how crazy you can get with c++ ;) That should be reserved for blogs IMHO.

My 2 cents, good day.

the first thing the existing std::visit example shows is the example you suggested, only in a slightly simpler form. --Cubbi (talk) 18:41, 15 September 2018 (PDT)

stackless description

Hi, I'd like to discuss a little bit about a revert you made here: --P12 06:00, 13 August 2019 (PDT)

as noted in the comment, that introduced implementation details into a lead intro that tries to be as simple as possible, and they were not totally correct (it's not "all variables", it's autos and temporaries whose lifetime crosses the suspension point, much like how lambdas don't capture everything in scope, only what's used.. and they are not necessarily on heap - the designers fought hard against making heap allocations unless required). Sure, the effect is as-if it captured everything on-heap, but that only reinforces the perception of inefficiency that delayed the coroutines so much. --Cubbi (talk) 08:30, 13 August 2019 (PDT)
Agreed, I just wanted to point out that some kind of description may be worthwhile in the introduction too. I'll try to think something of simple and correct. --P12 13:08, 14 August 2019 (PDT)

MediaWiki:Gadget-standard revisions.js

About 2 months ago I left a section on the talk page about fixing the Vector skin, but it went unnoticed. Since you're an active admin, could you please incorporate the changes or respond there? Ojou (talk) 23:04, 29 October 2020 (PDT)

css and gadget


Could you update css and gadget of If you don't want to do it by yourself, would you change those files protection?

Because Coliru gadget is not registered, "run this code" cannot be worked on korean site. And some styled texts are not displayed like english site. Sapziller (talk) 07:01, 16 January 2022 (PST)

Modifications made to frexp; please check and comment

I made mods to the frexp function to use as a model for others; at your convenience, please check it out and make modifications and I'll use it as I translate onto Spanish. Thx!

compiler support

Thanks for the note on C++11 and C++14 tables, good catch!

Thinking out loud, would it be reasonable to remove Cray entirely, then--including the C++11 and C++14 tables--and would editing the header/footer be safe then?

The rationale for dropping these Cray versions entirely is that they haven't been supported any more and the Cray compilers are a product shipped with and supported for Cray hardware--thus, in practice, there is no use case where a user would be using a historical version of the compiler and wanted to look up the C++11 or C++14 for that version.