Построение вашего матричного типа на typedef из unordered_map
, похоже, не обеспечивает хорошую инкапсуляцию.Конечно, на первый взгляд, это, кажется, предлагает очень бережливое решение.Но, в конце концов, проблема с operator=
является прекрасной демонстрацией того, как этот вид конструкции конфликтует с принципом открытия / закрытия .
Поэтому мое предложение будет заключаться в том, чтобы обернуть базовую структуру данных в класс для улучшения инкапсуляции (для простоты я использую double вместо общего указателя):
using coord1D = std::size_t; // time to forget about typedef ?
using coord2D = std::pair<coord1D,coord1D>;
struct pair_hash {
template <class T1, class T2>
std::size_t operator() (const std::pair<T1, T2> &pair) const {
return std::hash<T1>()(pair.first) ^ std::hash<T2>()(pair.second);
}
};
class matrix {
std::unordered_map<coord2D, double, pair_hash> m;
public:
auto& operator[] (pair<int,int> p) {
if (p.first>p.second)
p = make_pair(p.second, p.first);
return m[p];
}
};
В этом случаеВы можете преобразовать параметр в operator[]
, чтобы сделать матрицу треугольной по конструкции, избегая избыточного кода и избыточного хранилища.
Демо:
matrix m;
m[make_pair(1,5)] = 27.2;
cout << m[make_pair(1,5)]<<" "<<m[make_pair(5,1)]<<endl;
Онлайн демо
Конечно, лучшим способом было бы определить общую матрицу и вывести ее в формуспециализированная треугольная матрица, в которой происходит преобразование координат.