gnzlbg / static_vector

A dynamically-resizable vector with fixed capacity and embedded storage

Home Page:https://gnzlbg.github.io/static_vector

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Relational operators as non-member function templates?

gnzlbg opened this issue · comments

@rhalbersma mentioned in the std-proposal thread:

Second, you define the op== and other relational operators as friends, which means they are generated as non-member functions at namespace scope. However, all other Standard containers are defined as non-member function templates. The difference is that the latter does not accept user-defined conversions, and the former does. Also they don't have to be friends either.

The best way to declare the relational operators op== and op< is as non-member non-friend function templates, that delegate to std::equal and std::lexicographical_compare on the embedded_vector's iterator range. Then the others can be defined as usual in terms of the former.

So I would propose

template <typename T, size_t Capacity>
bool operator==(inline_vector<T, Capacity> const& lhs, inline_vector<T, Capacity> const& rhs)  noexcept
{
    return std::equal(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
}

template <typename T, size_t Capacity>
bool operator<(inline_vector<T, Capacity> const& lhs, inline_vector<T, Capacity> const& rhs)  noexcept
{
    return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
}

I will work this a bit differently because std::equal and std::lexicographical_compare are not constexpr in C++17, but I will give it the exact same semantics.

@rhalbersma i've fixed this.