Сделать операторы сравнения контейнеров независимыми от типа аллокатора

smertigdon
smertigdon

Мотивация следующая. Следующий код не будет компилироваться 

#include <memory>
#include <vector>
 
template <class T>
struct custom_allocator : std::allocator<T> {};
 
int main() {
	std::vector<int, std::allocator<int>> a;
	std::vector<int, custom_allocator<int>> b;
	a == b; // compilation error, no match for 'operator=='
	return 0;
}

Причина очевидна - оператор сравнения определён лишь для объектов идентичных типов, что включает в себя и типы аллокаторов. Однако сам аллокатор не влияет на внутреннюю структуру контейнера и, следовательно, не должен влиять на логику различных операций над контейнером, которые его не меняют (точнее, на более широкий класс - которые не вызывают выделения памяти).

Предложение следующее - заменить сигнатуру операторов сравнения с 

template <class T, class Allocator>
bool operator==(const std::vector<T, Allocator>& lhs, const std::vector<T, Allocator>& rhs) { ... }

на

template <class T, class Allocator1, class Allocator2>
bool operator==(const std::vector<T, Allocator1>& lhs, const std::vector<T, Allocator2>& rhs) { ... }

Аналогично для всех прочих операторов сравнения, а также для всех контейнеров. 

Обратную совместимость это не ломает, зато немного упрощает жизнь разработчику.

 

P.S. Есть ощущение, что данную идею можно развить и дальше, например, на конструкторы копирования, операторы присваивания (не учитывая их перемещающие аналоги). Возможно, стоит обдумать какую-то концепцию, которая позволит вырезать тип аллокатора из типа-контейнера и оперировать универсальным образом везде, где не происходит перераспределения памяти.

16
рейтинг
4 комментария
yndx-antoshkka
Мне идея нравится. Если нужна помощь с написанием proposal - говорите, помогу.
yndx-antoshkka
Antervis
А может имеет смысл сразу ориентироваться на Concepts && Ranges? В том плане, что два контейнера разных типов (vector<int>, list<int>) тоже могут сравниваться лексикографически. Что-то вроде inline bool operator == (const Container &lhs, const Container &rhs) { return equal(lhs,rhs); }
Antervis
yndx-antoshkka
Antervis, стоит проработать оба варианта и дать комитету выбор между "для каждого контейнера добавляем операторы сравнения" и "операторы сравнения для всех контейнеров сразу"
yndx-antoshkka
Antervis
yndx-antoshkka, так ведь одно является подмножеством второго
Antervis
Другие идеи
Группа создана, чтобы собирать предложения к стандарту C++, организовывать их внутренние обсуждения, помогать готовить их для отправки в комитет и защищать на общих собраниях в рабочей группе по С++ Международной организации по стандартизации (ISO).