Commit b471fe2a authored by Nathan G Bronson's avatar Nathan G Bronson Committed by Facebook GitHub Bot

avoid operator!= ambiguity in c++20 (#1544)

Summary:
F14 map `iterator` doesn't define `operator==` or `operator!=` to itself.
Those member functions take `const_iterator` as the right-hand side,
relying on the ability to convert implicitly from `iterator` to
`const_iterator`. This interacts poorly with c++20's default equality
operators, triggering clang's `-Wambiguous-reversed-operator`.

This diff replaces the equality member functions with friends that use
the same left-hand and right-hand types.  iterator != const_iterator
will now compile by implicitly converting the left-hand-side and then
calling `operator!=(const_iterator const&, const_iterator const&)`,
rather than calling `iterator::operator!=(const_iterator const&)`.
This resolves the ambiguity in c++20, and should work fine on earlier
versions, although I have not tested it on anything except c++17.

Pull Request resolved: https://github.com/facebook/folly/pull/1544

Test Plan: does it build?

Reviewed By: yfeldblum

Differential Revision: D27479086

Pulled By: shixiao

fbshipit-source-id: 0d42dbdc056cec58a36de3a816883736a761d0f6
parent 692d08fb
...@@ -469,11 +469,13 @@ class ValueContainerIterator : public ValueContainerIteratorBase<ValuePtr> { ...@@ -469,11 +469,13 @@ class ValueContainerIterator : public ValueContainerIteratorBase<ValuePtr> {
return cur; return cur;
} }
bool operator==(ValueContainerIterator<ValueConstPtr> const& rhs) const { friend bool operator==(
return underlying_ == rhs.underlying_; ValueContainerIterator const& lhs, ValueContainerIterator const& rhs) {
return lhs.underlying_ == rhs.underlying_;
} }
bool operator!=(ValueContainerIterator<ValueConstPtr> const& rhs) const { friend bool operator!=(
return !(*this == rhs); ValueContainerIterator const& lhs, ValueContainerIterator const& rhs) {
return !(lhs == rhs);
} }
private: private:
...@@ -698,11 +700,13 @@ class NodeContainerIterator : public BaseIter<ValuePtr, NonConstPtr<ValuePtr>> { ...@@ -698,11 +700,13 @@ class NodeContainerIterator : public BaseIter<ValuePtr, NonConstPtr<ValuePtr>> {
return cur; return cur;
} }
bool operator==(NodeContainerIterator<ValueConstPtr> const& rhs) const { friend bool operator==(
return underlying_ == rhs.underlying_; NodeContainerIterator const& lhs, NodeContainerIterator const& rhs) {
return lhs.underlying_ == rhs.underlying_;
} }
bool operator!=(NodeContainerIterator<ValueConstPtr> const& rhs) const { friend bool operator!=(
return !(*this == rhs); NodeContainerIterator const& lhs, NodeContainerIterator const& rhs) {
return !(lhs == rhs);
} }
private: private:
...@@ -936,11 +940,13 @@ class VectorContainerIterator : public BaseIter<ValuePtr, uint32_t> { ...@@ -936,11 +940,13 @@ class VectorContainerIterator : public BaseIter<ValuePtr, uint32_t> {
return cur; return cur;
} }
bool operator==(VectorContainerIterator<ValueConstPtr> const& rhs) const { friend bool operator==(
return current_ == rhs.current_; VectorContainerIterator const& lhs, VectorContainerIterator const& rhs) {
return lhs.current_ == rhs.current_;
} }
bool operator!=(VectorContainerIterator<ValueConstPtr> const& rhs) const { friend bool operator!=(
return !(*this == rhs); VectorContainerIterator const& lhs, VectorContainerIterator const& rhs) {
return !(lhs == rhs);
} }
private: private:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment