Pull to refresh
16
0

Пользователь

Send message

Ну вот на самом деле у вас и будет тысяча строк которые не работают без сахара в компиляторе и не реализуют половину фич из цпп.

Цпп iota имеет, а хаскель не имеет. Сравнение не уместно. Приходите с хаскель примером когда он это научится.

Греп ничего не даёт. Инвариант необходимый для ансейф блока зачастую приходит снаружи

Не сравнивайте свои списки с С++ ренжами

list1 = foo 5 (Bound 10)
list2 = foo 5 Infinity

Во-первых неудобно, везде в других языках просто пишем iota(5, 10) или iota(5) не говоря уже про языки где есть именованные аргументы.
Во-вторых у вас на тайплевеле потерялась информация о том закрытый ренж или открытый

(!!) :: [a] -> Int -> a

WARNING: This function takes linear time in the index.

не годится

за час пердолинга не смог

auto safeIota(auto&& start, auto&& end) {
  if (start <= end) return rv::iota(FWD(start), FWD(end));
  else return rv::iota(start, start);
}

делается за пол секунды

safeIota :: (Ord a, Enum a) => a -> a -> [a]

А где хотя бы случай когда второй аргумет равен бесконечности? Где поддержка operator[i] у хаскель списка?

  1. miri это никакая не "формальная верификация" это санитайзер

  2. coq уже больше похоже на правду, но реально им никто не пользуется

  3. наличие санитайзеров для раст подтверждает что нифига формально не верифицировано и по факту для отлова уб используются утилиты заимствованные из С++. Только интеграция с раст там хуже.

Ренжи по сравнению ч циклами дают инверсию контроля

Потму что ваши методы не должны принимать контейнеры, а должны принимать ренжи. Если код использующий контейнеры дженерик, то надо через 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() но это очень ограниченное решение.

Тут проблема в самом std::min, можно было бы сделать перегрузку для rvalue ссылок.

Надо писать const auto& и не думать

Либо вы уже ушли, и вам пофиг что он там сделал, либо у вас не работает код ревью.

Если с# закрывает ваши задачи то хорошо, не стоит брать с++. Высокоуровневые языки это размен контроля на простоту.

Ключевое слово "потенциально". Просто мазать constexpr везде смысла мало. Современный С++ даёт возможность специализировать поведение программы для разных данных через метапрограммирование и constexpr как его часть. Но для этого нужно писать соответсвующий код. Мы рассуждаем в контексте других языков, где таких возможностей попросту нет. Значит сравнивать надо с С++ кодом в котором так же эти возможности не задёствуются, и лишние кейворды вроде constexpr/noexcept не возникают.

Если вы не знаете что делает constexpr то следует ознакомится с документацией прежде чем писать чушь в комментариях. Заодно узнаете про consteval.

constexpr - перенести часть вычислений в компайлтайм

const propagation оптимизация работает и в си без всяких constexpr

Information

Rating
5,091-st
Registered
Activity