С++. Шаблонная магия и нафиг это надо.

С шаблонами в С++ можно делать много интересных вещей. Например, можно писать такой код, в котором никто никогда не разберется, по крайней мере, без поллитры. При этом, что характерно, код будет на 100% корректным, соответствовать всевозможным coding conventions и вообще идеально подходить в качестве примера отличного кода для очередной умной книжки о программировании. Еще можно развлекаться – делаешь в коде небольшую ошибочку и наблюдаешь, как компилятор истерично выплевывает в консоль мегабайты ругательств, которые можно выдавать в качестве домашнего задания нерадивому коллеге, если Вы, конечно, садист и уверены, кто коллега этот не знает Вашего домашнего адреса.

А еще можно делать шаблонную магию. Например, кое-какие вычисления можно делать во время компиляции. Все уже видели, как считать числа Фибоначчи или факториал там. Еще можно вычислить логарифм.

template <unsigned long _number, unsigned char _base>
struct tLog

{
      enum { value = 1 + tLog<_number/_base, base> };
};

template <unsigned char _base>
struct tLog<1>
{
     enum { value = 0 };
}

template <unsigned char _base>
struct tLog<0>
{
     enum { value = 0 };
}

В принципе, большинство подобных трюков сводятся к тому, что программист заставляет компилятор делать кое-какие вычисления во время компиляции. Рекурсивно. В данном случае финт ушами позволяет прикинуть целое значение логарифма путем деления аргумента на основание. Сколько раз удастся разделить, пока не упремся в ноль, такое и значение. Конечно, все это можно назвать более умными (читай непонятными) словами, но суть от этого не изменится. Кстати, самое вкусное в подобных трюках остается на десерт – шаблоны позволяют получить очень эффективный код. В данном случае в бинарник программы вместо шаблонного ужаса попадет результат вычисления в виде константы.

Выразив свою индивидуальность таким кодом в проекте, можно заслужить уважение и почет коллег. Впрочем, чаще получается получить несколько матерных слов в свой адрес, но это мелочи жизни и они нас не должны волновать, не так ли? Главное ведь – это идея!

Ладно, индивидуальность выразили, тут все свои, время отвечать на вопрос, зачем это все нужно. Кроме использования в качестве средства самовыражения, конечно. И вот тут начинаются интересности, ибо объяснить необходимость наличия таких заклинаний в коде бывает затруднительно. Они, конечно, представляют академический интерес, но о реальных применениях слышать приходилось мало кому

На самом деле умение считать логарифм во время компиляции может пригодиться в реальной жизни. Мне, например, оно помогло посчитать ширину строки, необходимой для представления числа для форматированного вывода. Еще можно вычислять объем памяти, необходимый для чего-нибудь эдакого, пока, правда, не придумал чего.

Как я уже сказал, выглядит это порой круто, но практическая ценность подобных извратов находится, как правило, в некоторой окрестности нуля. Но это не значит, что все шаблонные трюки настолько бесполезные – недавно мне удалось построить очень красивый конечный автомат с явной таблицей переходов, причем, применив особые заклинания, я заставил компилятор проверять полноту таблицы и отсутствие дублирующих переходов. Об этом напишу попозже

Leave a comment

3 Comments.

  1. Каждый раз, когда гляжу на подобный извраты в плюсном коде, задаю себе два вопроса: 1) Неужели самому не противно? 2) Когда все эти добрые люди напишут на шаблонах Forth и, наконец, успокоятся? :)

  2. Нет, не противно. Выпускники факультета программирования с использованием макаронных изделий и сочувствующие постоянно подгоняют более противные экземпляры :)

  3. Тут отличная статья есть про enum в C++ – http://www.quizful.net/page/enum-types-c
    Кстати, там же и про template в C++ тест пройти можно.

Leave a Reply

Yandex Mail.ru Google LiveJournal myOpenId Flickr claimId Blogger Wordpress OpenID Yahoo Technorati Vidoop Verisign AOL


[ Ctrl + Enter ]

9 visitors online now
9 guests, 0 members
Max visitors today: 11 at 07:38 am MST
This month: 23 at 05-03-2012 08:23 am MST
This year: 29 at 01-23-2012 02:50 am MST
All time: 45 at 02-23-2011 09:11 am MST