So, I've been working on a Vector implementation for an assignment and noticed some strange Clang-Tidy suggestions while implementing the iterators.
The iterator must have an iterator& operator++() and an iterator operator++(int) overload, per the required specification. Now, when I try to define iterator operator++(int), which essentially copies the iterator, increments the pointer and then returns that copy, Clang-Tidy complains:
Overloaded 'operator++' returns a non-constant object instead of a constant object type
This should (apparently) be resolved by changing the return type to const iterator, a technique that is otherwise very rare. Changing the signature accordingly, though, makes Clang-Tidy complain again:
Return type 'const Vector::iterator' (aka 'const Vector::Iterator') is 'const'-qualified at the top level, which may reduce code readability without improving const correctness
The default fix action in CLion 2020.3.2 actually removes the const, which brings back the original Clang-Tidy warning.
I'd like to know what's the "right" way to implement operator++(int). Should I ignore Clang-Tidy in this case? If yes, which signature should I choose?
Thanks!
Edit 1
The following post does not answer my question: Other StackOverflow Question. In fact, I came across this post before I decided to ask my own question, because it did not answer it for me. The problem is that in the linked post, two options are suggested:
- Do as clang-tidy says, but then maybe lose the benfeits of move semantics.
- lvalue ref-qualify the overload instead, to mimic the little ints.
(1) would mean exactly what I've done, namely putting a const in front of the iterator return type. As stated in my post, this triggers the second Clang-Tidy warning.
(2) does not remove the Clang-Tidy warning. Also I am not sure if I am allowed to use it under the restrictions of the assignment.
Also, here's a minimal reproducible example:
class Iterator { ptr_type ptr; // whatever your pointer type is // some code public: explicit Iterator(ptr_type _ptr) : ptr{ _ptr } {} // Option #1 Iterator operator++(int) { // Clang-Tidy warning #1 will be triggered here Iterator copy{ ptr }; ++ptr; return copy; } // Option #2 const Iterator operator++(int) { // Clang-Tidy warning #2 will be triggered here Iterator copy{ ptr }; ++ptr; return copy; } // more code };
&at the end does not get rid of the warning, either. I first referred to exactly this post to find an answer, but because it didn't help me, I decided to ask a new question.