Daily bit(e) C++. std::equal_to, std::not_equal_to, std::greater, std::less, std::greater_equal, std::less_equal and std::compare_three_way

Добавлено 25 сентября 2023 в 04:54

Daily bit(e) C++ #227, функциональные объекты компараторов: std::equal_to, std::not_equal_to, std::greater, std::less, std::greater_equal, std::less_equal и std::compare_three_way.

Daily bit(e) C++

Функциональные объекты: std::equal_to, std::not_equal_to, std::greater, std::less, std::greater_equal, std::less_equal и (C++20) std::compare_three_way реализуют соответствующие операции сравнения.

Эти объекты могут служить компараторами для алгоритмов, которые их принимают. Это избавляет нас от необходимости писать лямбду только для того, чтобы вернуть результат сравнения двух аргументов.

#include <functional>
#include <algorithm>
#include <vector>

struct A {};
struct B {};
bool operator<(A,B) { return false; }


std::vector<int> data{8,4,1,3,2,9,6,5,7};
// Версия с явной специализацией:
std::ranges::sort(data, std::greater<int>{});
// data == {9,8,7,6,5,4,3,2,1}

// Явная специализация может вызвать проблемы
// с неявными преобразованиями.
std::vector<double> fpoint{4.2,4.1,4.3,4.4,4.9,4.5};
std::ranges::sort(fpoint, std::greater<int>{});
// Неуказанный порядок, но технически это должно быть запрещено.
// Причина: все элементы равны при преобразовании в int.

// Специализация <void> с выводом типа из C++14
std::ranges::sort(fpoint, std::greater<>{});
// Аргументы компаратора будут выведены как double.
// fpoint == {4.9,4.5,4.4,4.3,4.2,4.1}

// Версия для диапазонов из C++20, аргументы выводятся всегда.
std::ranges::sort(data, std::ranges::greater{});

// При использовании с неоднородными типами поведение отличается.
int x = 4; double y = 4.2;
// Старый стиль, явно указанный тип с принудительным
// неявным преобразованием
bool cmp1 = std::less<int>{}(x,y);
bool cmp2 = std::less<double>{}(x,y);
// cmp1 == false, cmp2 == true

// C++14, выводятся оба аргумента, operator< потенциально
// применяется к разнородному типу.
bool cmp3 = std::less<>{}(x,y); // <int,double>
// cmp3 == true

// C++20, выводятся оба аргумента, 
// но ограничено более строгой семантикой.
bool cmp4 = std::ranges::less{}(x,y);
// cmp4 == true

std::less<>{}(A{},B{}); // OK
// std::ranges::less{}(A{},B{}); // не скомпилируется

Открыть пример на Compiler Explorer.

Теги

C++ / CppDaily bit(e) C++STL / Standard Template Library / Стандартная библиотека шаблоновПрограммирование

На сайте работает сервис комментирования DISQUS, который позволяет вам оставлять комментарии на множестве сайтов, имея лишь один аккаунт на Disqus.com.

В случае комментирования в качестве гостя (без регистрации на disqus.com) для публикации комментария требуется время на премодерацию.