Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Излишние ограничения std::max и std::min #113

Open
PavelSharp opened this issue Nov 26, 2024 · 1 comment
Open

Излишние ограничения std::max и std::min #113

PavelSharp opened this issue Nov 26, 2024 · 1 comment

Comments

@PavelSharp
Copy link

Здравствуйте!
Благодарю за написание увлекательного и мотивирующего сборника об остроугольности языка C++. В особенности нравиться воздушность тона, его неформальность, и безоблачная картина с которой начинается абсолютное большинство глав, затем, как правило, краски сгущаются, становясь тяжелыми и мрачными, ещё мгновение - и перед нами покажется та часть семантики языка, которой было суждено оказаться жертвой непрерывной и динамичной эволюции, начало которой было положено более 40 лет.

Переходя к делу, я бы хотел обратить внимание на функции std::min и std::max, сигнатуры которых налагают искусственное ограничение в виде работы только с константными ссылками. И это первая очевидная проблема. Второе, что лежит на поверхности, умело балансирует между проблемой и стремлением к безопасности дизайна, это - наличие только одного шаблонного параметра в упомянутых функциях, из-за чего не находится место для потенциально возможного оператора <, сравнивающего разнотипные аргументы. Кроме того, при стандартном вызове std::min(a,b) вывод аргументов шаблона может отличаться от наших ожиданий, это хорошо видно на следующем пример:

signed char x = -1;
unsigned short y = 2;
int z = std::min(x, y); //doe's not compile

Тезисно, что включить в главу?
При написание соответствующей главы, можно оперировать тем, что std::min/max позиционируют себя как высокоуровневая замена всеми любимой пары макросов, встречаемых в огромном числе проектов старой школы, а также возможность замены прямого написание тернарного оператора. Увы, подобного рода новаторство совсем не эквивалентно старой технике, ибо
int z = x<y?x:y - успешно компилируется

Теперь перейдем к ранее описанной проблеме константной ссылочности и отсутствия обработки rvalue ссылок. Предполагая о сравнение тяжелых объектов, которые созданы функциями, т.е. строка: auto obj = std::min(foo(), bar()); приведет к вызову конструктора копирования а не перемещения. Хотя, здесь некоторая моя неуверенность из-за RVO.

Переходя к эпилогу, стоит привести "лекарство от всех болезней", попробовав реализовать min прогрессивным образом на относительно современном C++14, а именно:

template<class TA, class TB>
constexpr decltype(auto) min2(TA&& a, TB&& b) {
	return (a < b) ? std::forward<TA>(a) : std::forward<TB>(b);
}

Думаю, даже при таком подходе возникают некоторые тонкие недостатки. В общем, оставляется на ваш профессиональный анализ😊

Источники

  1. Why does std::max return by const&?
  2. Improved min/max
@Nekrolm
Copy link
Owner

Nekrolm commented Nov 26, 2024

Спасибо за отзыв!

Я подумаю, что можно добавить. У прогрессивного варианта с тернарным оператором точно есть проблемы со слайсингом: см. https://github.com/Nekrolm/ubbook/blob/master/lifetime/ternary_operator.md

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants