Search code examples
c++operator-overloadingclang-tidy

Clang-Tidy is ambiguous: What should operator++(int) return?


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:

  1. Do as clang-tidy says, but then maybe lose the benfeits of move semantics.
  2. 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
};

Solution

  • https://clang.llvm.org/extra/clang-tidy/checks/cert/dcl21-cpp.html

    According to this page, that first warning is deprecated and will be removed in clang-tidy version 19. I suggest to disable the warning in the config file or just ignore it.