Le code usuel demeure tel quel...
|
#include <algorithm>
template <class T, std::size_t N>
class Tableau {
public:
using value_type = T;
using size_type = std::size_t;
using iterator = value_type*;
using const_iterator = const value_type*;
private:
value_type elems[N]{ };
public:
constexpr size_type size() const {
return N;
}
iterator begin() noexcept {
return std::begin(elems);
}
const_iterator begin() const noexcept {
return std::begin(elems);
}
iterator end() noexcept {
return std::end(elems);
}
const_iterator end() const noexcept {
return std::end(elems);
}
Tableau() = default;
template <class U>
Tableau(const Tableau<U,N> &autre) {
using std::copy;
copy(autre.begin(), autre.end(), begin());
}
//
// Sainte-Trinité implicitement Ok
//
constexpr value_type& operator[](size_type n) {
return elems[n];
}
constexpr value_type operator[](size_type n) const {
return elems[n];
}
bool operator==(const Tableau &autre) const {
using std::equals;
return equals(begin(), end(), autre.begin());
}
bool operator!=(const Tableau &autre) const {
return !(*this == autre);
}
}; |
... et les opérations de comparaison sont, somme toute, plutôt simples.
Voilà!
|
template <class T, std::size_t M, std::size_t N>
constexpr bool operator==(const Tableau<T,M>&, const Tableau<T,N>&) {
return false;
}
template <class T, std::size_t M, std::size_t N>
constexpr bool operator!=(const Tableau<T,M>&, const Tableau<T,N>&) {
return true;
}
template <class T, class U, std::size_t N>
bool operator==(const Tableau<T,N> &t0, const Tableau<U,N> &t1) {
using namespace std;
return equals(begin(t0), end(t0), begin(t1));
}
template <class T, class U, std::size_t N>
bool operator!=(const Tableau<T,N> &t0, const Tableau<U,N> &t1) {
return !(t0 == t1);
}
template <class T, class U, std::size_t M, std::size_t N>
constexpr bool operator==(const Tableau<T,M>&, const Tableau<U,N>&) {
return false;
}
template <class T, class U, std::size_t M, std::size_t N>
constexpr bool operator!=(const Tableau<T,M>&, const Tableau<U,N>&) {
return true;
} |