Talk:cpp/language/operators
Contents |
[edit] Re-using code between const and non-const function overloads, such as operator[]
Refer to revision 76323, which followed the standard idiom for implementing this code-reuse. Refer to Stack Overflow discussion. The revision to follow this pattern was reverted, but I think it was correct and should be re-instated. --Drummist180 (talk) 09:45, 16 February 2015 (PST)
- Proposed code (logic in the const overload) can't be used if the const overload returns by value, and the comment on the diff was irrelevant (no UB either way). I do agree that the approach with logic in the const overload has a good reference. Let's see if it can be represented. --Cubbi (talk) 10:14, 16 February 2015 (PST)
- I'm not convinced that it is ever correct to implement the const overload in terms of the non-const overload, because it does indeed lead to undefined behavior for reasons discussed in the link I provided. Casting away the const-ness of an object leads to undefined behavior if that object is then modified. Consider that compiler optimizations may make assumptions about the state of an object being constant, so if the state unexpectedly changes, which can happen without the developer knowing it can happen, then the compiler assumptions are no longer correct. This results in undefined behavior.
- Quoting from Scott Meyer's Effective C++ 3rd Edition, page 25: "Even more worth knowing is that trying to do things the other way around -- avoiding duplication by having the const version call the non-const version -- is not something you want to do. [...] having a const member function call a non-const one is wrong: the object could be changed."
- This site should avoid examples that potentially invoke undefined behavior. Prefacing the code with "if it does not actually modify *this" is promoting really bad programming practice.
- Regarding your recent edit: "reuse const overload if it returns by reference and if it does not return a reference to an object that is actually declared const." This is mentioned in the linked discussion. The class should probably not have a non-const overload implemented if the data is declared const. So the "actual access" approach would also not be appropriate. So I do not think it is helpful to preface the logic with the qualifying comment.
- --Drummist180 (talk) 13:00, 16 February 2015 (PST)
- Both directions of re-use are perfectly safe as shown (no, if some compiler makes "assumptions" in this case, it is blatantly non-compliant). Both directions of reuse admit the possibility of UB if some unusual code is added, and I would argue that operator[] that modifes a non-mutable member of *this (aka std::map::operator[]) is as unusual as operator[] that references an object that is declared const ( std::string::operator[]). I understand many people take Scott's books as gospel, and this isn't the place to pick them apart. For an impartial summary of operator overloading, it would be simpler to not attempt discussing the possibilities of reuse for operator[] at all. The real merit of this page (in my opinion) is showing that there are two overloads. --Cubbi (talk) 16:09, 16 February 2015 (PST)
[edit] No list of overload-able operators
This page has a table at the end that lists operators, but not all of them are overloadable. In particular, "." and "?:" can't be overloaded. 71.23.61.96 10:06, 28 February 2015 (PST)
- it is in cpp/language/operators#Restrictions, in the beginning of the page. The table in the end is just a "see also" table that points at the pages describing the built-in operator behavior.. perhaps it can say 'built-in' somwhere. --Cubbi (talk) 11:24, 28 February 2015 (PST)
[edit] On sequencing in &&, || and comma
The page says, the sequencing restrictions are not present until C++17 - that is, since C++17 the sequencing will be strict left-to-right. This, however, seems to be in contradiction with (also non-formal) source, Oulu Trip Report, where they say P0145 was taken in, with exception to a function call expression - where sequencing of argument expression is left to the compilers.
Aren't overriden &&, || and comma operators "just" function calls and fall under this exception to P0145?
- function call expressions are as before, but calls to overloaded operators are no longer "just" function calls. The expression a || b sequences a before b regardless of whether || is built-in or overloaded. (edited to hopefully make it clearer) --Cubbi (talk) 08:27, 24 November 2016 (PST)
[edit] canonical assignment operator
The canonical assignment operator implementation looks like it is a leftover from the mid-90s. But not knowing how things are done here, I thought I would first start a discussion, rather than just going in and replacing the implementation.
This Stackoverflow answer starts with a detailed critique of an assignment operator that looks like Nick had lifted it from this very page. He then discusses the topic at length and arrives at what had been promoted as the canonical version for ~20 years:
T& operator=(T rhs) { this->swap(rhs); return *this; }
I think this should replace the current version.
Any objections?
--84.177.217.27 10:41, 30 September 2020 (PDT)
- this version is already discussed on this page, look for "T& T::operator=(T arg) noexcept" --Cubbi (talk) 12:04, 30 September 2020 (PDT)
Yes, but that canonical version comes with needlessly restricting conditions, at the end of the section, while at the top of the paragraph there is a version from the mid-90s, without any restricting language. The canonical form is, unrestricted, exactly what newbies should do, and therefore it should be at the top of the paragraph, and the other one should not be mentioned at all. --84.177.217.27
- Resource reusage is good, and if you're defining an assignment operator, you (should) have a resource. I like the current presentation of assignment as is. On another note, are you aware that you're describing both implementations of the assignment operator as "from the 90s"? (not that being from the 90s is necessarily good/bad/relevant) --Ybab321 (talk) 04:45, 16 November 2020 (PST)