-
Notifications
You must be signed in to change notification settings - Fork 73
Description
Здравствуйте!
Благодарю за написание увлекательного и мотивирующего сборника об остроугольности языка 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);
}
Думаю, даже при таком подходе возникают некоторые тонкие недостатки. В общем, оставляется на ваш профессиональный анализ😊
Источники