Комментарии 44
Интересно только для новичков в Шаблонах С++…
-8
Я лично никогда не мог понять фишку шаблонов. Теперь я понял все. Спасибо
+3
скорость компиляции (вычисления) можно значительно повысить в ~2 раза, если начинать проверять хотя бы с n/2:
templatestruct is_prime
{
static const bool value = is_prime_rec<n, (n+1)/2 — 1>::value;
};
templatestruct is_prime
{
static const bool value = is_prime_rec<n, (n+1)/2 — 1>::value;
};
+2
достаточно до n^0.5
0
Вычисление квадратного корня во время компиляции — это круто :)
+3
Ну так а что, на тех же самых шаблонах, каким-нибудь делением пополам. Числа-то целые.
0
да, действительно несложно =)
template struct while_f {
template <int res, int x>
struct calc_res {
const static int tmp = (res+x/res)/2;
typedef typename while_f<(res > tmp)>::template calc_res<tmp<res?tmp:res, x> a;
static const int value = a::value;
};
};
template <> struct while_f {
template <int res, int x>
struct calc_res {
static const int value = res;
};
};
template struct sqrt {
static const int value = while_f::calc_res<(x+1)/2, x>::value;
};
template <> struct sqrt<0> {
static const int value = 0;
};
// assert(sqrt<81>::value == 9);
+1
Я-то имел в виду что-то такое:
template<unsigned V> struct Sqrt { template<unsigned L, unsigned R> struct Sqrt_eval { static const unsigned M = (L + R + 1) / 2; static const bool D = M * M < V; static const bool Stop = L + 1 >= R; static const unsigned N = R * R > V ? L : R; static const unsigned value = Sqrt_eval<Stop ? N : D ? M : L, Stop ? N : D ? R : M>::value; }; template<unsigned M> struct Sqrt_eval<M, M> { static const unsigned value = M; }; static const unsigned value = Sqrt_eval<0, V>::value; };
+2
абсолютно согласен
0
Шаблоны C++ позволяют обрабатывать некоторые значения параметров шаблона особым образом (частичная специализация).
Если при этом использованы все параметры шаблона, то это не частичная, а полная специализация.
«Частичность» специализации в том, что она фиксируя или вводя зависимости между какими-то параметрами шаблона оставляет и независимые шаблонные параметры, формируя шаблон с меньшим количеством параметров.
+4
Списки типов, вычисление простых чисел на шаблонах… День Александреску на хабре?
+1
Коллеги, на минутку отодвиньте в сторонку старый, весь поросший обратной совместимостью C++, и обратите внимание на более современные языки, где не надо так извращаться. В разработке D и его стандартной библиотеки активно участвует Андрей Александреску — даже ему, мастеру template-fu, надоело плести шаблонные интриги в C++
+2
Спасибо, но мы уж как-нибудь с С++ справимся. Да и в реальном проекте никто не даст заменить С++ на D.
+4
А я и не уговариваю бросаться писать в production на D прямо сейчас, просто призываю не стоять на месте и изучать новые технологии; можно же и для души написать что-нибудь, поиграться с языком, чтобы знать его сильные и слабые стороны. Компилятор D медленно, но верно избавляется от багов, и когда он дойдёт до кондиции — грех не попробовать этот язык в новом проекте, благо что из него выкинули львиную долю C++ных костылей, косяков и шероховатостей. Ну а если вы работаете «на дядю», и «дядя» — упрямый, то у вас выбора, конечно, нет.
+1
Ну D-то недалеко от C++ ушёл. Если действительно интересуют современные языки, можно посмотреть на Nemerle, Haskell, Coq, Agda2.
+1
Ну так D — язык системного программирования, а из более высокоуровневых я пока отдаю предпочтение Common Lisp и Python.
Nemerle сразу отброшу как платформозависимый (да, я знаю про mono, но: наезд Oracle на Google из-за Java, политика Microsoft), Haskell мне не нравится сильным уклоном в чистое ФП (я хочу программировать, используя разные парадигмы, и все — одинаково легко), а про остальные не слышал — посмотрю, что за звери.
Nemerle сразу отброшу как платформозависимый (да, я знаю про mono, но: наезд Oracle на Google из-за Java, политика Microsoft), Haskell мне не нравится сильным уклоном в чистое ФП (я хочу программировать, используя разные парадигмы, и все — одинаково легко), а про остальные не слышал — посмотрю, что за звери.
0
Как только подрастете, то поймете, что мы не всегда вольны выбирать язык, часто он выбирает нас сам.
-1
Хехе, относительно недавно была статья про вычисление факториалов схожим способом. Вообще, это довольно интересно. Спасибо за статью :)
0
Надо реализовать решето Эратосфена :-) Правда вот на шаблонах это будет тяжко сделать.
0
Мне кажется, в этой статье был мощный подтекст. А именно — сравнение со Scheme: типа посмотрите какое убожество C++ и как все красиво и понятно на функциональном языке Scheme, разбухший синтаксис с костылями в виде шаблонов против изящного функционального стиля. Хотя кому-то могут не понравиться скобки.
+2
А Scheme в приведенных примерах тоже все считает на этапе компляции? Я честно не в курсе. Ну и лично мне красивым и понятным показался как раз вариант на С++. А в Scheme больше напрягают не скобочки, а обратная польская запись.
0
Только она не обратная.
0
Скобочки и префиксная запись напрягают, когда на Scheme и других диалектах Lisp не пишешь, а только теоретизируешь о них. Да и назвать шаблонную магию объёмом в несколько раз больше, чем соответствующий код на Scheme, красивой… Такой код — просто proof of concept: использовать его в повседневной разработке — бессмысленно и беспощадно.
+1
Скобочки и префиксная запись напрягают, когда на Scheme и других диалектах Lisp не пишешь, а только теоретизируешь о них.
Не сомневаюсь. Более того, думаю, что если бы в школе меня учили писать не z=2*x + 3*y, а что-то типа (setq z (+ (* 2 x) (* 3 y))), то Scheme была бы мне близка и понятна. Что характерно, на С++ я тоже особо не пишу в последние годы, что не мешает мне спокойно читать его код.
Да и назвать шаблонную магию объёмом в несколько раз больше, чем соответствующий код на Scheme, красивой…Ну во-первых красота измеряется не объемом. Во-вторых само понятие красоты очень субъективно, поэтому постом выше я написал «лично мне». А в-третьих, на мой взгляд, тут сравнивать не совсем корректно. Код на Scheme в статье описан в императивном стиле, а на шаблонах — в декларативном(что-то близкое к pattern matching из функциональных языков).
0
Код на обоих языках в функциональном стиле. От того, что в шаблонах на C++ есть немного pattern matching, меняется способ записи, а не идея алгоритма.
0
Ну так про идею алгоритма я ничего и не говорил. Речь идет об отсутствии управляющих конструкций типа if в шаблоном коде статье, т.е. об элементах декларативности. Впрочем, не сомневаюсь, что и пример на Scheme можно переписать соответствующим образом.
0
Тот факт, что нет явных if не делает код декларативным. Декларативным был бы код, где явно написано, что простое число это число, обладающее такими-то свойствами, и т. д. В шаблонном коде идёт перебор чисел и явная проверка этих свойств.
0
Смотрите, я пишу «т.е. об элементах декларативности.»
Вы отвечаете — «Тот факт, что нет явных if не делает код декларативным.»
Вам не кажется, что наши утверждения не вступают в противоречие и таким образом нет предмета спора?
Вы отвечаете — «Тот факт, что нет явных if не делает код декларативным.»
Вам не кажется, что наши утверждения не вступают в противоречие и таким образом нет предмета спора?
0
Я считаю, что тут нет даже элемента декларативности.
0
Ну а я и некоторые другие, считаю что pattern matching это элемент декларативности. Предлагаю на этом остановиться.
0
Императивный код:
Лёгким движением руки:
становится декларативным?
def imperative(x: Int) {
if(x == 1) {
println("one")
} else if(x == 2) {
println("two")
} else {
println("many")
}
}
Лёгким движением руки:
def declarative(x: Int) = x match {
case 1 => println("one")
case 2 => println("two")
case _ => println("many")
}
становится декларативным?
0
На самом деле да, несмотря на неудачный пример(правильней сравнить, например, разбор списка). Ибо в первом варианте вы просто описывает поток выполнения с операторами перехода. Неймон в полный рост. А во втором случает вы по сути задаете набор «предикат — значение функции». По сути описываете какая ваша функция.
Можно шагнуть чуть дальше и писать что-то типа
Можно шагнуть чуть дальше и писать что-то типа
declarative(1) = "one"
declarative(2) = "two"
declarative(_) = "many"
0
В Scheme можно вызывать произвольные функции на этапе компиляции (в том числе и пользовательские).
0
Scheme был использован потому что у него семантика управляющих конструкций и модель вычислений схожа с шаблонами.
+1
Реализация BOOST_STATIC_ASSERT в чём-то близка к описанному, хотя уже и используется в реальных задачах.
0
Зарегистрируйтесь на Хабре , чтобы оставить комментарий
Вычисление простых чисел на шаблонах C++