Ответ 1
Предложение прозрачных операторов операторов существует как способ иметь обобщенные функторы, расположенные в <functional>
. Я лично считаю, что у самого предложения есть очень хороший пример, который поможет проиллюстрировать его необходимость. Однако я пойду дальше и попытаюсь объяснить это также.
Предположим, что у вас есть функция, очень простая функция:
template<typename T, typename U>
auto less_than(T&& t, U&& u) -> decltype(std::forward<T>(t) < std::forward<U>(u)) {
return std::forward<T>(t) < std::forward<U>(u);
}
Однако вы хотите использовать эту обобщенную функцию в заголовке <algorithm>
. У вас есть два варианта, чтобы сделать его функтором структуры:
struct MyLessThanFunctor {
template<typename T, typename U>
auto operator()(T&& t, U&& u) -> decltype(std::forward<T>(t) < std::forward<U>(u)){
return std::forward<T>(t) < std::forward<U>(u);
}
};
Или в С++ 14, чтобы сделать полиморфную лямбда:
[](auto&& t, auto&& u) -> decltype(auto) {
return std::forward<decltype(t)>(t) < std::forward<decltype(u)>(u);
}
Оба они очень многословны, когда они используются в таком алгоритме:
int main() {
std::vector<int> v = {112,12,1281271,1919101,29181,412,1 };
std::sort(std::begin(v), std::end(v), MyLessThanFunctor()); // one
std::sort(std::begin(v), std::end(v), [](auto&& t, auto&& u) -> decltype(auto) {
return std::forward<decltype(t)>(t) < std::forward<decltype(u)>(u);
});
}
Это предложение стремится сделать его более компактным и обобщенным, сделав это вместо этого:
std::sort(std::begin(v), std::end(v), std::less<>());
Это дает вам идеальную пересылку и решает проблемы с усечением или проблемами, возникающими в результате изменения контейнера, но не базовым типом, назначенным контейнером, как указано в документе.
Предположим, что у вас есть не обобщенный функтор:
struct Functor {
bool operator()(uint32_t a, uint32_t b) {
return a < b;
}
};
И вы используете его с вашим std::vector<uint32_t>
, и все работает отлично, но вы забываете, что ваш функтор не обобщается и не использует его со своим std::vector<uint64_t>
. Вы видите проблему, которая возникла? Элементы будут усечены перед сравнением, что, вероятно, не то, что пользователь хотел. Обобщенные функции решают эту проблему перед вами, прежде чем они возникнут.