Во-первых неудобно, везде в других языках просто пишем iota(5, 10) или iota(5) не говоря уже про языки где есть именованные аргументы. Во-вторых у вас на тайплевеле потерялась информация о том закрытый ренж или открытый
miri это никакая не "формальная верификация" это санитайзер
coq уже больше похоже на правду, но реально им никто не пользуется
наличие санитайзеров для раст подтверждает что нифига формально не верифицировано и по факту для отлова уб используются утилиты заимствованные из С++. Только интеграция с раст там хуже.
Потму что ваши методы не должны принимать контейнеры, а должны принимать ренжи. Если код использующий контейнеры дженерик, то надо через algorithm работать
auto min(auto&& a, auto&& b) -> std::remove_reference_t<decltype(a)>
requires std::is_rvalue_reference_v<decltype(a)> || std::is_rvalue_reference_v<decltype(b)> {
static_assert(std::is_same_v<std::remove_reference_t<decltype(a)>, std::remove_reference_t<decltype(b)>>);
return (a < b) ? std::forward<decltype(a)>(a) : std::forward<decltype(b)>(b);
}
template<typename T>
auto min(const T& a, const T& b) -> const T& {
return (a < b) ? a : b;
}
Или сделать всегда move() но это очень ограниченное решение.
Ключевое слово "потенциально". Просто мазать constexpr везде смысла мало. Современный С++ даёт возможность специализировать поведение программы для разных данных через метапрограммирование и constexpr как его часть. Но для этого нужно писать соответсвующий код. Мы рассуждаем в контексте других языков, где таких возможностей попросту нет. Значит сравнивать надо с С++ кодом в котором так же эти возможности не задёствуются, и лишние кейворды вроде constexpr/noexcept не возникают.
Ну вот на самом деле у вас и будет тысяча строк которые не работают без сахара в компиляторе и не реализуют половину фич из цпп.
Цпп iota имеет, а хаскель не имеет. Сравнение не уместно. Приходите с хаскель примером когда он это научится.
Греп ничего не даёт. Инвариант необходимый для ансейф блока зачастую приходит снаружи
Не сравнивайте свои списки с С++ ренжами
Во-первых неудобно, везде в других языках просто пишем iota(5, 10) или iota(5) не говоря уже про языки где есть именованные аргументы.
Во-вторых у вас на тайплевеле потерялась информация о том закрытый ренж или открытый
не годится
делается за пол секунды
А где хотя бы случай когда второй аргумет равен бесконечности? Где поддержка operator[i] у хаскель списка?
miri это никакая не "формальная верификация" это санитайзер
coq уже больше похоже на правду, но реально им никто не пользуется
наличие санитайзеров для раст подтверждает что нифига формально не верифицировано и по факту для отлова уб используются утилиты заимствованные из С++. Только интеграция с раст там хуже.
Ренжи по сравнению ч циклами дают инверсию контроля
Потму что ваши методы не должны принимать контейнеры, а должны принимать ренжи. Если код использующий контейнеры дженерик, то надо через algorithm работать
Можно как-то так сделать
Или сделать всегда
move()но это очень ограниченное решение.Тут проблема в самом
std::min, можно было бы сделать перегрузку для rvalue ссылок.Надо писать
const auto&и не думатьЛибо вы уже ушли, и вам пофиг что он там сделал, либо у вас не работает код ревью.
Если с# закрывает ваши задачи то хорошо, не стоит брать с++. Высокоуровневые языки это размен контроля на простоту.
Ключевое слово "потенциально". Просто мазать constexpr везде смысла мало. Современный С++ даёт возможность специализировать поведение программы для разных данных через метапрограммирование и constexpr как его часть. Но для этого нужно писать соответсвующий код. Мы рассуждаем в контексте других языков, где таких возможностей попросту нет. Значит сравнивать надо с С++ кодом в котором так же эти возможности не задёствуются, и лишние кейворды вроде constexpr/noexcept не возникают.
Если вы не знаете что делает constexpr то следует ознакомится с документацией прежде чем писать чушь в комментариях. Заодно узнаете про consteval.
const propagation оптимизация работает и в си без всяких constexpr
Сочувствую вашей травме