<?xml version='1.0' encoding="utf-8"?>
      <rss version='2.0'>
      <channel>
      <title>Форум на Исходниках.RU</title>
      <link>https://forum.sources.ru</link>
      <description>Форум на Исходниках.RU</description>
      <generator>Форум на Исходниках.RU</generator>
  	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=191418&amp;view=findpost&amp;p=1608410</guid>
        <pubDate>Tue, 19 Jun 2007 18:36:23 +0000</pubDate>
        <title>TR1. Technical Report on C++ Library Extensions.</title>
        <link>https://forum.sources.ru/index.php?showtopic=191418&amp;view=findpost&amp;p=1608410</link>
        <description><![CDATA[Unreal Man: <div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=191418&view=findpost&p=1608150'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>archimed7592 &#064; <time class="tag-quote__quoted-time" datetime="2007-06-19T18:05:02+04:00">19.06.07, 14:05</time></span><div class='quote '>Я имею ввиду сохранить хэш для хранимых в контейнере элементов.</div></div><br>
В смысле хэши? А разве можно как-то иначе? :blink:<br>
<br>
<div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=191418&view=findpost&p=1608150'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>archimed7592 &#064; <time class="tag-quote__quoted-time" datetime="2007-06-19T14:05:02+00:00">19.06.07, 14:05</time></span><div class='quote '>Зачем? Принимает значение. Вычисляем хэш для этого значения. </div></div><br>
Вот на это-то у тебя и уйдёт много времени, если значение – это большая строка. Представь, что строка состоит из сотни символов. Хэш обычно вычисляется с учётом всех символов. А для сравнения двух строк обычно требуется 1 – 3 посимвольных сравнений. Даже с учётом логарифмической сложности получается не так уж и много. Только совпадающие строки при сравнении тратят много времени. В итоге или получается вровень, или хэшированный контейнер показывает незначительное преимущество, IMHO, не оправдывающее всей этой возни с хэшами (по крайней мере, так у меня выходило).]]></description>
        <author>Unreal Man</author>
        <category>C/C++: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=191418&amp;view=findpost&amp;p=1608150</guid>
        <pubDate>Tue, 19 Jun 2007 14:05:02 +0000</pubDate>
        <title>TR1. Technical Report on C++ Library Extensions.</title>
        <link>https://forum.sources.ru/index.php?showtopic=191418&amp;view=findpost&amp;p=1608150</link>
        <description><![CDATA[archimed7592: <div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=191418&view=findpost&p=1608110'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>Unreal Man &#064; <time class="tag-quote__quoted-time" datetime="2007-06-19T13:47:27+00:00">19.06.07, 13:47</time></span><div class='quote '>Во-первых, иногда в этом в принципе нет смысла, т.к. поиск по конкретно взятой строке однократный</div></div><br>
Я имею ввиду сохранить хэш для хранимых в контейнере элементов.<br>
<br>
<br>
<div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=191418&view=findpost&p=1608110'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>Unreal Man &#064; <time class="tag-quote__quoted-time" datetime="2007-06-19T13:47:27+00:00">19.06.07, 13:47</time></span><div class='quote '>Во-вторых, будет ли метод find, который принимает именно hash вместо самого ключа?</div></div><br>
Зачем? Принимает значение. Вычисляем хэш для этого значения. Ищем хэш, в сохранённых, равный этому. Если находим, то сравниваем строки уже функтором equal_to.<br>
В принципе, нужно посмотреть требования к контейнерам с точки зрения complexity - тогда всё встанет на свои места :).]]></description>
        <author>archimed7592</author>
        <category>C/C++: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=191418&amp;view=findpost&amp;p=1608110</guid>
        <pubDate>Tue, 19 Jun 2007 13:47:27 +0000</pubDate>
        <title>TR1. Technical Report on C++ Library Extensions.</title>
        <link>https://forum.sources.ru/index.php?showtopic=191418&amp;view=findpost&amp;p=1608110</link>
        <description><![CDATA[Unreal Man: <div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=191418&view=findpost&p=1607869'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>archimed7592 &#064; <time class="tag-quote__quoted-time" datetime="2007-06-19T11:56:15+00:00">19.06.07, 11:56</time></span><div class='quote '>А сохранять хэш не судьба? </div></div><br>
Во-первых, иногда в этом в принципе нет смысла, т.к. поиск по конкретно взятой строке однократный. Во-вторых, будет ли метод find, который принимает именно hash вместо самого ключа?]]></description>
        <author>Unreal Man</author>
        <category>C/C++: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=191418&amp;view=findpost&amp;p=1607869</guid>
        <pubDate>Tue, 19 Jun 2007 11:56:15 +0000</pubDate>
        <title>TR1. Technical Report on C++ Library Extensions.</title>
        <link>https://forum.sources.ru/index.php?showtopic=191418&amp;view=findpost&amp;p=1607869</link>
        <description><![CDATA[archimed7592: <div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=191418&view=findpost&p=1607739'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>Unreal Man &#064; <time class="tag-quote__quoted-time" datetime="2007-06-19T10:54:10+00:00">19.06.07, 10:54</time></span><div class='quote '>Неравные строки заканчивают сравниваться, как только находится первое несовпадение соответствующих символов. А сколько ты будешь вычислять hash своей длинной строки? </div></div><br>
А сохранять хэш не судьба? :huh: <br>
<br>
<br>
<div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=191418&view=findpost&p=1607751'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>LuckLess &#064; <time class="tag-quote__quoted-time" datetime="2007-06-19T10:59:25+00:00">19.06.07, 10:59</time></span><div class='quote '>Както проводил сравнение.. давно еще... имеет смысл только если строки очень длинные и при этом крайне похожие, но разные ;)</div></div>Ну это, имхо, от реализации сильно зависит :)]]></description>
        <author>archimed7592</author>
        <category>C/C++: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=191418&amp;view=findpost&amp;p=1607751</guid>
        <pubDate>Tue, 19 Jun 2007 10:59:25 +0000</pubDate>
        <title>TR1. Technical Report on C++ Library Extensions.</title>
        <link>https://forum.sources.ru/index.php?showtopic=191418&amp;view=findpost&amp;p=1607751</link>
        <description><![CDATA[LuckLess: <div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=191418&view=findpost&p=1607739'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>Unreal Man &#064; <time class="tag-quote__quoted-time" datetime="2007-06-19T10:54:10+00:00">19.06.07, 10:54</time></span><div class='quote '>Строки заканчивают сравниваться, как только находится первое несовпадение соответствующих символов. А сколько ты будешь вычислять hash своей длинной строки?</div></div><br>
 :yes:  :yes: Както проводил сравнение.. давно еще... имеет смысл только если строки очень длинные и при этом крайне похожие, но разные  ;)]]></description>
        <author>LuckLess</author>
        <category>C/C++: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=191418&amp;view=findpost&amp;p=1607739</guid>
        <pubDate>Tue, 19 Jun 2007 10:54:10 +0000</pubDate>
        <title>TR1. Technical Report on C++ Library Extensions.</title>
        <link>https://forum.sources.ru/index.php?showtopic=191418&amp;view=findpost&amp;p=1607739</link>
        <description><![CDATA[Unreal Man: <div class='tag-quote'><a class='tag-quote-link' href='https://forum.sources.ru/index.php?showtopic=191418&view=findpost&p=1606939'><span class='tag-quote-prefix'>Цитата</span></a> <span class='tag-quote__quote-info'>archimed7592 &#064; <time class="tag-quote__quoted-time" datetime="2007-06-19T00:44:17+00:00">19.06.07, 00:44</time></span><div class='quote '>Возьмём ключ типа string - в случае поиска в обычном контейнере произойдёт log2N сравнений. А если строки по 50 мб? Накладно. </div></div><br>
А вычислять hash не накладно? :D<br>
Неравные строки заканчивают сравниваться, как только находится первое несовпадение соответствующих символов. А сколько ты будешь вычислять hash своей длинной строки?]]></description>
        <author>Unreal Man</author>
        <category>C/C++: Общие вопросы</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=191418&amp;view=findpost&amp;p=1606939</guid>
        <pubDate>Tue, 19 Jun 2007 00:44:17 +0000</pubDate>
        <title>TR1. Technical Report on C++ Library Extensions.</title>
        <link>https://forum.sources.ru/index.php?showtopic=191418&amp;view=findpost&amp;p=1606939</link>
        <description><![CDATA[archimed7592: <span class='tag-size' data-value='14' style='font-size:14pt;'><strong class='tag-b'><span class='tag-u'><span class="tag-color tag-color-named" data-value="green" style="color: green">TR1. Technical Report on C++ Library Extensions</span></span></strong></span><br>
<br>
<span class='tag-size' data-value='11' style='font-size:11pt;'><strong class='tag-b'><span class="tag-color tag-color-named" data-value="blue" style="color: blue"><span class='tag-u'>Введение.</span></span></strong></span><br>
<br>
В мае 2001 <a class='tag-url' href='http://www.open-std.org/JTC1/SC22/WG21/' target='_blank'>комитет по стандартизации языка С++</a> объявил(<a class='tag-url' href='http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2001/n1314.htm' target='_blank'>n1314</a>) о приёме предложений и пожеланий для расширения функциональности <a class='tag-url' href='http://ru.wikipedia.org/wiki/%D0%A1%2B%2B#.D0.A1.D1.82.D0.B0.D0.BD.D0.B4.D0.B0.D1.80.D1.82.D0.BD.D0.B0.D1.8F_.D0.B1.D0.B8.D0.B1.D0.BB.D0.B8.D0.BE.D1.82.D0.B5.D0.BA.D0.B0' target='_blank'>Стандартной Библиотеки С++</a>.<br>
Комитет озвучил некоторый список того, чего он желал бы видеть в качестве пожеланий.<br>
Также, комитет немного формализовал способ заявления о своём пожелании. Пожелание должно содержать следующие пункты: мотивация(зачем нужно нововведение; описание проблемы), влияние на стандарт(нужны ли для нововведения изменения в текущем стандарте - как в синтаксисе, так и в библиотечной его части), принятые решения(описание предлагаемого решения проблемы) и примерный текст для включения в стандарт(необязательно).<br>
Таким образом, каждый желающий мог поучаствовать в усовершенствовании любимого языка, а точнее - его библиотеки.<br>
Так, уже в октябре 2001 был составлен начальный список пожеланий(<a class='tag-url' href='http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2001/n1325.html' target='_blank'>n1325</a>), который включал в себя только пожелания перенести некоторую функциональность из Boost. В дальнейшем список начал пополняться не только библиотеками из Boost. И тем не менее, первый, опубликованный в сентябре 2003, черновик TR1 почти полностью состоял из формализованной документации Boost.<br>
<br>
TR1 - это Technical Report. Документы этого класса не являются нормативными(в отличии от IS - International Standard) и делаются специально на скорость, опуская много долгих и нудных формальностей.<br>
<br>
Здесь будет более-менее подробно рассмотрен последний черновик TR1, опубликованный в июле 2005.<br>
<br>
Все сущности из TR1 находятся в пространстве имён std::tr1.<br>
<br>
Знать содержимое TR1 нужно. Точно так же, как нужно знать содержимое STL - без этого, эффективно программировать на С++ невозможно.<br>
Несмотря на то, что оффициально TR1 имеет лишь рекомендательный характер, в реальности он <em class='tag-i'>уже</em> включён в рабочий черновик следующего стандарта(C++09) и начиная с 2009 года(возможно чуть позже), программирование с использованием TR1 будет считаться таким же обыкновенным явлением, как и программирование с использованием STL(он будет частью STL). Т.к. за один день с такой объёмной библиотекой не освоишься(нужно разобраться, попрактиковаться, &quot;набить шишки&quot; и т.д.), то рекомендую людям, проффессионально занимающимся(или планирующим проффесионально заняться) программированием на С++ ознакомится с TR1(если ещё не знакомы) и начать его эксплуатацию(уже есть реализация от Boost). Ну и последний аргумент в пользу TR1: не нужно изобретать велосипедов :).<br>
<br>
<hr><br>
<ul class="tag-list"><span class='tag-size' data-value='11' style='font-size:11pt;'><strong class='tag-b'>Ссылки по теме</strong></span></li><li>Что такое стандарт:<br>
<a class='tag-url' href='http://forum.sources.ru/index.php?showtopic=68025' target='_blank'>Что такое стандарт С++ и где его взять</a></li><li>Немного о готовящемся стандарте С++09:<br>
<a class='tag-url' href='http://forum.sources.ru/index.php?showtopic=190375' target='_blank'>Новый стандарт C++: C++09</a></li><li>Оффициальные документы, описывающие TR1:<br>
<a class='tag-url' href='http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1836.pdf' target='_blank'>Draft Technical Report on C++ Library Extensions(n1836)</a><br>
<a class='tag-url' href='http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1837.pdf' target='_blank'>Library Extension Technical Report - Issues List(n1837)</a></li><li>Реализация TR1 командой <a class='tag-url' href='http://boost.org/' target='_blank'>Boost</a>:<br>
<a class='tag-url' href='http://boost.org/libs/tr1/index.html' target='_blank'>Boost.TR1</a></li><li><span class="tag-color tag-color-named" data-value="gray" style="color: gray">Немного о TR2:<br>
тут будет ссылка(потом) :)</span></li></ul><br>
<hr><br>
<br>
<span class='tag-size' data-value='11' style='font-size:11pt;'><strong class='tag-b'>Reference wrapper</strong></span>(<a class='tag-url' href='http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2003/n1453.html' target='_blank'>n1453</a>)<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">template &#60;class T&#62; class reference_wrapper; // сама обёртка</div><div class="code_line">&nbsp;</div><div class="code_line">// ф-ции помощники(аля std::make_pair для std::pair)</div><div class="code_line">template &#60;class T&#62; reference_wrapper&#60;T&#62; ref(T&amp;);</div><div class="code_line">template &#60;class T&#62; reference_wrapper&#60;const T&#62; cref(const T&amp;);</div><div class="code_line">template &#60;class T&#62; reference_wrapper&#60;T&#62; ref(reference_wrapper&#60;T&#62;);</div><div class="code_line">template &#60;class T&#62; reference_wrapper&#60;const T&#62; cref(reference_wrapper&#60;T&#62;);</div></ol></div></div></div></div><script>preloadCodeButtons('1');</script><br>
<br>
Обёртка для работы со ссылками.<br>
Представляет из себя объект, хранящий ссылку типа T, неявно конвертируемый к типу T &amp;, с перегруженным оператором operator()(...).<br>
<ul class="tag-list"><strong class='tag-b'>Предполагаемое применение.</strong></li><li>Там, где вывод(deduce) типа шаблонного аргумента приведёт к нессылочному типу(когда желаемым является ссылочный тип).<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">void f(int &amp; r)</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp;++r;</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">template&#60;class F, class T&#62; void g(F f, T t) { f(t); }</div><div class="code_line">&nbsp;</div><div class="code_line">int main()</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp;int i = 0;</div><div class="code_line">&nbsp;&nbsp; &nbsp;g(f, i);</div><div class="code_line">&nbsp;&nbsp; &nbsp;cout &#60;&#60; i &#60;&#60; endl; // 0</div><div class="code_line">&nbsp;&nbsp; &nbsp;g(f, ref(i));</div><div class="code_line">&nbsp;&nbsp; &nbsp;cout &#60;&#60; i &#60;&#60; endl; // 1</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;int i1(5), i2(10);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;function&#60;MyClass()&#62; f1 = bind(std::plus(), i1, i2); // создасться функтор в котором i1 и i2 будут сохранены по значению</div><div class="code_line">&nbsp;&nbsp; &nbsp;function&#60;MyClass()&#62; f2 = bind(std::plus(), cref(obj1), cref(obj2)); // создасться функтор в котором будут сохранены ссылки на i1 и i2.</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;i1 *= 2;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;int i3 = f1(); // будет использовано старое значение i1 т.е. результат 15.</div><div class="code_line">&nbsp;&nbsp; &nbsp;int i4 = f2(); // будет использовано текущее значение i1 т.к. рузультат 20.</div><div class="code_line">}</div></ol></div></div></div></div></li><li>Там, где использование ссылок недопустимо(в контейнерах, к примеру).<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">std::list&#60;int&#62; numbers;</div><div class="code_line">std::vector&#60;reference_wrapper&#60;int&#62; &#62; number_refs;</div><div class="code_line">for(int i = 0; i &#60; 100; ++i)</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp;numbers.push_back(4*i*i^2 - 10*i + 3);</div><div class="code_line">&nbsp;&nbsp; &nbsp;number_refs.push_back(ref(numbers.back()));</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">std::sort(number_refs.begin(), number_refs.end());</div></ol></div></div></div></div></li><li>В биндерах(и вообще там, где используются функторы). Если обёртка хранит функтор(указатель на ф-цию или любую другую вызываемую сущность), то её экземпляр тоже становится вызываемой сущностью.<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">struct counting_less</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp;typedef bool result_type;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;template&#60;typename T&#62; bool operator()(const T&amp; x, const T&amp; y) </div><div class="code_line">&nbsp;&nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;++count;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;return x &#60; y;</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;int count;</div><div class="code_line">};</div><div class="code_line">&nbsp;</div><div class="code_line">// ...</div><div class="code_line">&nbsp;</div><div class="code_line">vector&#60;int&#62; elements;</div><div class="code_line">// fill elements</div><div class="code_line">counting_less cl;</div><div class="code_line">sort(elements.begin(), elements.end(), ref(cl));</div><div class="code_line">std::cout &#60;&#60; cl.count &#60;&#60; &quot; comparisons in sort\n&quot;;</div></ol></div></div></div></div></li></ul><br>
<hr><br>
<br>
<span class='tag-size' data-value='11' style='font-size:11pt;'><strong class='tag-b'><span class="tag-color tag-color-named" data-value="blue" style="color: blue"><span class='tag-u'>Smart Pointers</span></span></strong></span>(<a class='tag-url' href='http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2003/n1450.html' target='_blank'>n1450</a>)<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">class bad_weak_ptr;</div><div class="code_line">&nbsp;</div><div class="code_line">template&#60;class T&#62; class shared_ptr;</div><div class="code_line">&nbsp;</div><div class="code_line">// shared_ptr comparisons</div><div class="code_line">template&#60;class T, class U&#62; bool operator==(shared_ptr&#60;T&#62; const&amp; a, shared_ptr&#60;U&#62; const&amp; b);</div><div class="code_line">template&#60;class T, class U&#62; bool operator!=(shared_ptr&#60;T&#62; const&amp; a, shared_ptr&#60;U&#62; const&amp; b);</div><div class="code_line">template&#60;class T, class U&#62; bool operator&#60;(shared_ptr&#60;T&#62; const&amp; a, shared_ptr&#60;U&#62; const&amp; b);</div><div class="code_line">&nbsp;</div><div class="code_line">// shared_ptr casts</div><div class="code_line">template&#60;class T, class U&#62; shared_ptr&#60;T&#62; static_pointer_cast(shared_ptr&#60;U&#62; const&amp; r);</div><div class="code_line">template&#60;class T, class U&#62; shared_ptr&#60;T&#62; dynamic_pointer_cast(shared_ptr&#60;U&#62; const&amp; r);</div><div class="code_line">template&#60;class T, class U&#62; shared_ptr&#60;T&#62; const_pointer_cast(shared_ptr&#60;U&#62; const&amp; r);</div><div class="code_line">&nbsp;</div><div class="code_line">// shared_ptr I/O</div><div class="code_line">template&#60;class E, class T, class Y&#62;</div><div class="code_line">basic_ostream&#60;E, T&#62;&amp; operator&#60;&#60; (basic_ostream&#60;E, T&#62;&amp; os, shared_ptr&#60;Y&#62; const&amp; p);</div><div class="code_line">&nbsp;</div><div class="code_line">// shared_ptr get_deleter</div><div class="code_line">template&#60;class D, class T&#62; D* get_deleter(shared_ptr&#60;T&#62; const&amp; p);</div><div class="code_line">&nbsp;</div><div class="code_line">// -----------------------------------------------------------------------------</div><div class="code_line">&nbsp;</div><div class="code_line">template&#60;class T&#62; class weak_ptr;</div><div class="code_line">&nbsp;</div><div class="code_line">// weak_ptr comparison</div><div class="code_line">template&#60;class T, class U&#62; bool operator&#60;(weak_ptr&#60;T&#62; const&amp; a, weak_ptr&#60;U&#62; const&amp; b);</div></ol></div></div></div></div><br>
<br>
Умные указатели - это специальные обёртки для обычных указателей(plain pointer, dumb pointer), которые так или иначе позволяют обезопасить себя от неприятнотей, которые встречаются при работе с обычными указателями. Но, тем не менее, они сами, как правило, имеют свои грабли и неприятные стороны :).<br>
<br>
Основное предназначение умных указателей - это автоматический контроль времени жизни динамических объектов, но бывают и другие предназначения.<br>
<br>
Умные указатели бывают разными. В STL ещё с 98 года есть std::auto_ptr. Его проблема в том, что объекты auto_ptr владеют объектом и при копировании(присваивании) у источника копирования(присваивания) хранимый указатель обнуляется. Т.е. на некоторый данный объект принципиально не может ссылаться более одного объекта auto_ptr. Реально, добиться того, чтобы на данный объект указывало несколько auto_ptr можно, но это UB(каждый из них выполнит delete ptr, чего делать несколько раз для одного и того же указателя нельзя).<br>
<br>
Предлагаемый умный указатель shared_ptr имеет такое название не случайно :). Shared(англ. общий) относится к стратегие владения: в отличии от auto_ptr со стратегией &quot;единственного владельца&quot;, у shared_ptr стратегия разделения владения объектом т.е. владельцев может быть много(shared ownership).<br>
<br>
Также предлагается т.н. observer(наблюдатель) weak_ptr. Имея shared_ptr можно создать weak_ptr, из которого потом можно будет опять создать shared_ptr но только при том условии, что объект ещё &quot;жив&quot;. Т.е weak_ptr не владеет объектом, он только &quot;наблюдает&quot; и если все shared_ptr уже &quot;умерли&quot;, то weak_ptr обнулится и при попытке создать из него shared_ptr бросится исключение bad_weak_ptr.<br>
<br>
<strong class='tag-b'>Предполагаемое применение.</strong><br>
Если вы раньше не использовали умных указателей, то перед &quot;употреблением&quot; советую почитать Мейрса, Александреску, Саттера и других на эту тему т.к. не зная <a class='tag-url' href='http://boost.org/libs/smart_ptr/shared_ptr.htm#BestPractices' target='_blank'>best practices</a> использовать умные укзатели немного проблематично(можно нагородить такого, что лучше бы их и не использовали :)).<br>
<br>
Если у старого доброго auto_ptr все области его применения очень хорошо известны и их очень мало, то у shared_ptr возможно применение почти везде, где возможно применение указателя.<br>
<ul class="tag-list">Характерное применение auto_ptr(только для сравнения).</li><li>Когда время жизни объекта ограничивается одной ф-цией(блоком кода, объектом), но использование объекта с автоматическим временем жизни по каким-то причинам невозможно(нежелательно).<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">void f()</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp;std::auto_ptr&#60; ProductA &#62; pa(Factory::instance().createProductA());</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;// ...</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;// здесь произойдёт деструкция pa и динамический объект удалится.</div><div class="code_line">}</div><div class="code_line">&nbsp;</div><div class="code_line">class MyWrapper</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp;std::auto_ptr&#60; MyBigObject &#62; obj;</div><div class="code_line">public:</div><div class="code_line">&nbsp;&nbsp; &nbsp;MyWrapper()</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;: obj(new MyBigObject())</div><div class="code_line">&nbsp;&nbsp; &nbsp;{ }</div><div class="code_line">};</div></ol></div></div></div></div></li><li>Там, где нужно <em class='tag-i'>явно</em> показать, что передаваемый как аргумент указатель должен указывать на объект с динамическим временем жизни и этот объект(как и контроль времени его жизни) переходит во владение этой ф-ции(она может передать владение куда-то ещё).<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">struct Interface</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp;virtual void foo() = 0;</div><div class="code_line">&nbsp;&nbsp; &nbsp;// ...</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;virtual ~Interface() { }</div><div class="code_line">};</div><div class="code_line">&nbsp;</div><div class="code_line">class MyClass</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp;std::auto_ptr&#60; Interface &#62; impl_;</div><div class="code_line">public:</div><div class="code_line">&nbsp;&nbsp; &nbsp;explicit MyClass(std::auto_ptr&#60; Interface &#62; impl)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;: impl_(impl)</div><div class="code_line">&nbsp;&nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">};</div><div class="code_line">&nbsp;</div><div class="code_line">template &#60; class T &#62;</div><div class="code_line">class Implementation</div><div class="code_line">&nbsp;&nbsp; &nbsp;: public Interface</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp;// ...</div><div class="code_line">};</div><div class="code_line">&nbsp;</div><div class="code_line">std::auto_ptr&#60; Interface &#62; impl1 (new Implementation&#60; int &#62;());</div><div class="code_line">std::auto_ptr&#60; Interface &#62; impl2 (new Implementation&#60; double &#62;());</div><div class="code_line">&nbsp;</div><div class="code_line">MyClass obj1(impl1);</div><div class="code_line">MyClass obj2(impl2);</div></ol></div></div></div></div></li><li>Там, где нужно <em class='tag-i'>явно</em> показать, что возвращаемый ф-цией указатель указывает на объект с динамическим временем жизни и этот объект(как и контроль времени его жизни) переходит во владение вызывавшей ф-ции(она может передать владение куда-то ещё).<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">class MyClass</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp;MyClass() { }</div><div class="code_line">&nbsp;&nbsp; &nbsp;MyClass(const MyClass &amp;);</div><div class="code_line">public:</div><div class="code_line">&nbsp;&nbsp; &nbsp;static std::auto_ptr&#60; MyClass &#62; createInstance()</div><div class="code_line">&nbsp;&nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;return std::auto_ptr&#60; MyClass &#62;(new MyClass());</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">};</div><div class="code_line">&nbsp;</div><div class="code_line">std::auto_ptr&#60; MyClass &#62; instance = MyClass::createInstance();</div><div class="code_line">MyClass::createInstance(); // утечки памяти не будет</div></ol></div></div></div></div></li></ul><br>
Характерное применение shared_ptr - везде, где динамическим объектом владеют несколько объектов/потоков/ф-ций и т.п.<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">struct Interface</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp;virtual void doSmallAction1() = 0;</div><div class="code_line">&nbsp;&nbsp; &nbsp;virtual void doSmallAction2() = 0;</div><div class="code_line">&nbsp;&nbsp; &nbsp;virtual void doSmallAction3() = 0;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;// ...</div><div class="code_line">&nbsp;&nbsp; &nbsp;virtual ~Interface() { }</div><div class="code_line">};</div><div class="code_line">&nbsp;</div><div class="code_line">class Factory;</div><div class="code_line">&nbsp;</div><div class="code_line">class StaticInterface</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp;friend class Factory;</div><div class="code_line">&nbsp;&nbsp; &nbsp;shared_ptr&#60; Interface &#62; impl;</div><div class="code_line">public:</div><div class="code_line">&nbsp;&nbsp; &nbsp;void doAction1()</div><div class="code_line">&nbsp;&nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;impl-&#62;doSmallAction1();</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;impl-&#62;doSmallAction3();</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;void doAction2()</div><div class="code_line">&nbsp;&nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;impl-&#62;doSmallAction2();</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;if (someCondition)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;impl-&#62;doSmallAction3();</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;impl-&#62;doSmallAction1();</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;// ...</div><div class="code_line">};</div><div class="code_line">&nbsp;</div><div class="code_line">class Factory</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp;// ...</div><div class="code_line">public:</div><div class="code_line">&nbsp;&nbsp; &nbsp;StaticInterface getInstaneById(size_t id)</div><div class="code_line">&nbsp;&nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;StaticInterface result;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;// ...</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;result.impl = std::shared_ptr&#60; Interface &#62;(new SomeImplementation(/* ... */));</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;return result;</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;// ...</div><div class="code_line">};</div></ol></div></div></div></div><br>
<br>
<hr><br>
<br>
<span class='tag-size' data-value='11' style='font-size:11pt;'><strong class='tag-b'>result_of</strong></span>(<a class='tag-url' href='http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2003/n1454.html' target='_blank'>n1454</a>)<br>
<br>
В стандартной библиотеке C++98/C++03 присутствуют алгоритмы. Большинство из них как один из аргументов берут вызываемую сущность. Т.е. указатель на ф-цию или функтор. Все, кто пользовался ими не раз испытывали нужду в том, чтобы, к примеру, зафиксировать первый аргумент вызываемой ф-ции и т.о. получить ф-цию, которой нужно передать на один аргумент меньше. Бывает, что нужно зафиксировать 3-й и 4-й аргументы, в пятый передать по ссылке и т.п. Бывают разные ситуации. Больше всего убивает, когда пытаешься реализовать более-менее сложную &quot;махинацию&quot; стандартными средствами библиотеки. А именно ptr_fun, mem_fun, bind1st, bind2nd и иже с ними. Вот зачем, к примеру, нужен ptr_fun? А затем, что для биндеров bind1st/2nd нужны специально оформленные функторы, а не &quot;какой-то голый указатель на ф-цию&quot;. Короче говоря, возможности по работе с обобщёнными функторами в стандартной библиотеке C++98/03 просто ужасают(особенно после того, как попробовать boost::bind).<br>
<br>
Любой, кто пытался реализовать ф-циональность похожую на boost::bind с нуля(я пытался под порывом вдохновения после прочтения одного из творений Александреску), практически сразу наступают на такую граблю: не существует стандартных средств, чтобы узнать какой тип будет у возвращённого произвольной ф-цией значения, вызванной с произвольным набором аргументов(с произвольными типами аргументов).<br>
Приходится изобретать колесо. А колёса мы не любим :).<br>
<br>
Итак, шаблон result_of позволяет решить вышеозвученную проблему, а именно, узнать тип возвращаемого ф-цией значения.<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">template &#60;class FunctionCallTypes&#62; // F(T1, T2, ..., TN)</div><div class="code_line">class result_of</div><div class="code_line">{</div><div class="code_line">public:</div><div class="code_line">&nbsp;&nbsp; &nbsp;typedef <span style='color:red'>unspecified</span> type;</div><div class="code_line">};</div></ol></div></div></div></div><br>
<br>
<strong class='tag-b'>Предполагаемое применение.</strong><br>
<br>
Лично я, кроме как в реализации своего биндера, пользы не вижу. Но у меня очень мал опыт разработки и реализации обобщённого кода. Уверен, что, раз эту штуку ввели, то достаточно часто возникает эта проблема. Т.о. предполагаемое применение - в любом обобщённом коде.<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">template&#60;typename F&#62; struct forwardN {</div><div class="code_line">&nbsp;&nbsp;template&#60;typename Args&#62; struct result;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;template&#60;typename T, typename T1, typename T2, ..., typename TN&#62;</div><div class="code_line">&nbsp;&nbsp;struct result&#60;T(T1, T2, ..., TN)&#62; {</div><div class="code_line">&nbsp;&nbsp; &nbsp;typedef typename result_of&#60;F(T1, T2, ..., TN)&#62;::type type;</div><div class="code_line">&nbsp;&nbsp;};</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;template&#60;typename T, typename T1, typename T2, ..., typename TN&#62;</div><div class="code_line">&nbsp;&nbsp;struct result&#60;const T(T1, T2, ..., TN)&#62; {</div><div class="code_line">&nbsp;&nbsp; &nbsp;typedef typename result_of&#60;const F(T1, T2, ..., TN)&#62;::type type;</div><div class="code_line">&nbsp;&nbsp;};</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;template&#60;typename T1, typename T2, ..., typename TN&#62;</div><div class="code_line">&nbsp;&nbsp;typename result&#60;forwardN(T1, T2, ..., TN)&#62;::type</div><div class="code_line">&nbsp;&nbsp;operator()(T1&amp; t1, T2&amp; t2, ..., TN&amp; tN) </div><div class="code_line">&nbsp;&nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp;return f(t1, t2, ..., tN);</div><div class="code_line">&nbsp;&nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;template&#60;typename T1, typename T2, ..., typename TN&#62;</div><div class="code_line">&nbsp;&nbsp;typename result&#60;const forwardN(T1, T2, ..., TN)&#62;::type</div><div class="code_line">&nbsp;&nbsp;operator()(T1&amp; t1, T2&amp; t2, ..., TN&amp; tN) const</div><div class="code_line">&nbsp;&nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp;return f(t1, t2, ..., tN);</div><div class="code_line">&nbsp;&nbsp;}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp;F f;</div><div class="code_line">};</div></ol></div></div></div></div><br>
<br>
<hr><br>
<br>
<span class='tag-size' data-value='11' style='font-size:11pt;'><strong class='tag-b'><span class="tag-color tag-color-named" data-value="blue" style="color: blue"><span class='tag-u'>Function object binders</span></span></strong></span>(<a class='tag-url' href='http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2003/n1455.htm' target='_blank'>n1455</a>)<br>
<br>
Как уже было сказано чуть выше, стандартная библиотека C++98/03 не содержит <em class='tag-i'>человеческих</em> средств для связывания функторов.<br>
<br>
Предлагается добавить человеческий биндер(из Boost :D).<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">template&#60;class F, class T1, class T2, ...., class TN&#62;</div><div class="code_line"><span style='color:red'>unspecified</span> bind(F f, T1 t1, T2 t2, ..., TN tN);</div><div class="code_line">&nbsp;</div><div class="code_line">template&#60;class R, class F, class T1, class T2, ...., class TN&#62;</div><div class="code_line"><span style='color:red'>unspecified</span> bind(F f, T1 t1, T2 t2, ..., TN tN);</div></ol></div></div></div></div><br>
Имеем две ф-ции. Вторая отличается от первой только тем, что можно явно указать желаемый тип возвращаемого значения и избавить биндер от необходимости вычислять возвращаемый тип тем более, что это не всегда возможно(насколько мне известно)... если явно указанный тип не совпадает с типом возвращаемого значения, то произойдёт преобразование(которое должно существовать - чудес не бывает :)).<br>
<br>
Используются очень просто:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">class Employee</div><div class="code_line">{</div><div class="code_line">public:</div><div class="code_line">&nbsp;&nbsp; &nbsp;// ...</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;int number() const;</div><div class="code_line">};</div><div class="code_line">&nbsp;</div><div class="code_line">std::vector&#60;Employee&#62; v;</div><div class="code_line">&nbsp;</div><div class="code_line">// sort by employee ID number</div><div class="code_line">&nbsp;</div><div class="code_line">std::sort(</div><div class="code_line">&nbsp;&nbsp; &nbsp;v.begin(),</div><div class="code_line">&nbsp;&nbsp; &nbsp;v.end(), </div><div class="code_line">&nbsp;&nbsp; &nbsp;bind(</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;std::less&#60;int&#62;(),</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;bind(&amp;Employee::number, _1),</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;bind(&amp;Employee::number, _2)));</div></ol></div></div></div></div><br>
<br>
<hr><br>
<br>
<span class='tag-size' data-value='11' style='font-size:11pt;'><strong class='tag-b'><span class="tag-color tag-color-named" data-value="blue" style="color: blue"><span class='tag-u'>Function object wrappers</span></span></strong></span>(<a class='tag-url' href='http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2002/n1402.html' target='_blank'>n1402</a>)<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">class bad_function_call; // исключение, которое можно получить при неправильном использовании function</div><div class="code_line">&nbsp;</div><div class="code_line">template&#60;class Function&#62; class function; // сама обёртка</div><div class="code_line">// Function == R (T1, T2, ..., TN)</div></ol></div></div></div></div><br>
<br>
Как вы могли заметить, упомянутый выше биндер возвращает значение типа &quot;unspecified&quot;... Это означает, что стандарт не оговаривает, какой тип должен возвращать биндер, главное, чтобы тип и само значение соответствовали определённым требованиям. Т.о. в чистом виде биндер можно использовать только с шаблонными ф-циями и сохранить значение, возвращённое биндером вне шаблона не получится...<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">sdt::transform(a.begin(), a.end(), b.begin(), a.begin(), bind(std::plus(), _1, _2)); // Имеет смысл.</div><div class="code_line">&nbsp;</div><div class="code_line">int x = bind(std::plus(), _1, _2)(10, 20); // x = 30. Проще написать x = 10 + 20, чем такое.</div></ol></div></div></div></div><br>
<br>
Очень часто возникает необходимость сохранить функтор, возвращённый биндером и при этом, использовать шаблоны не получается из-за архитектурных особенностей. К примеру, события - они хранятся в классе обычной кнопки. Никакой специализации кнопки для того, чтобы добавить обработчик события делать никто не будет(да и что, если обработчик нужно в run-time менять на другой?).<br>
<br>
Итак, предлагается обёртка, которая может хранить в себе <em class='tag-i'>любую</em> вызываемую сущность, подходящую под заданную сигнатуру(тип возвращаемого значения + количество и типы аргументов). Замечу, что она сама является вызываемой сущностью. Правда, за её универсальностью скрывается коварный минус: она полиморфна откуда следует, что будет дополнительный расход процессорного времени из-за полиморфного оверхэда.<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">function&#60;int(int,int) f = bind(std::plus(), _1, _2); // сохраняем функтор</div><div class="code_line">sdt::transform(a.begin(), a.end(), b.begin(), a.begin(), bind(std::plus(), _1, &nbsp;_2)); // получаем производительную трансформацию.</div><div class="code_line">sdt::transform(a.begin(), a.end(), b.begin(), a.begin(), f); // получаем overhead из-за полиморфизма.</div><div class="code_line">&nbsp;</div><div class="code_line">// зато, есть и большие плюсы - обёртку можно хранить в обычном объекте как обработчик события, к примеру</div><div class="code_line">class</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp;std::deque&#60; function&#60; bool(int, int) &#62; &#62; events;</div><div class="code_line">protected:</div><div class="code_line">&nbsp;&nbsp; &nbsp;// ...</div><div class="code_line">&nbsp;&nbsp; &nbsp;void raiseOnClickEvent(int x, int y)</div><div class="code_line">&nbsp;&nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;for (...)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if ((*i)(x, y)) // call handler</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;break;</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">public:</div><div class="code_line">&nbsp;&nbsp; &nbsp;// ...</div><div class="code_line">&nbsp;&nbsp; &nbsp;void connectHandler(const function&#60; bool(int, int) &#62; &amp;handler, bool connectToEnd = true)</div><div class="code_line">&nbsp;&nbsp; &nbsp;{</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;if (connectToEnd)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;events.push_back(handler);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;events.push_front(handler);</div><div class="code_line">&nbsp;&nbsp; &nbsp;}</div><div class="code_line">};</div></ol></div></div></div></div><br>
<br>
<hr><br>
<br>
<span class='tag-size' data-value='11' style='font-size:11pt;'><strong class='tag-b'>Type traits</strong></span>(<a class='tag-url' href='http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2003/n1424.htm' target='_blank'>n1424</a>)<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">// primary type categories:</div><div class="code_line">template &#60;class T&#62; struct is_void;</div><div class="code_line">template &#60;class T&#62; struct is_integral;</div><div class="code_line">template &#60;class T&#62; struct is_floating_point;</div><div class="code_line">template &#60;class T&#62; struct is_array;</div><div class="code_line">template &#60;class T&#62; struct is_pointer;</div><div class="code_line">template &#60;class T&#62; struct is_reference;</div><div class="code_line">template &#60;class T&#62; struct is_member_object_pointer;</div><div class="code_line">template &#60;class T&#62; struct is_member_function_pointer;</div><div class="code_line">template &#60;class T&#62; struct is_enum;</div><div class="code_line">template &#60;class T&#62; struct is_union;</div><div class="code_line">template &#60;class T&#62; struct is_class;</div><div class="code_line">template &#60;class T&#62; struct is_function;</div><div class="code_line">// composite type categories:</div><div class="code_line">template &#60;class T&#62; struct is_arithmetic;</div><div class="code_line">template &#60;class T&#62; struct is_fundamental;</div><div class="code_line">template &#60;class T&#62; struct is_object;</div><div class="code_line">template &#60;class T&#62; struct is_scalar;</div><div class="code_line">template &#60;class T&#62; struct is_compound;</div><div class="code_line">template &#60;class T&#62; struct is_member_pointer;</div><div class="code_line">// type properties:</div><div class="code_line">template &#60;class T&#62; struct is_const;</div><div class="code_line">template &#60;class T&#62; struct is_volatile;</div><div class="code_line">template &#60;class T&#62; struct is_pod;</div><div class="code_line">template &#60;class T&#62; struct is_empty;</div><div class="code_line">template &#60;class T&#62; struct is_polymorphic;</div><div class="code_line">template &#60;class T&#62; struct is_abstract;</div><div class="code_line">template &#60;class T&#62; struct has_trivial_constructor;</div><div class="code_line">template &#60;class T&#62; struct has_trivial_copy;</div><div class="code_line">template &#60;class T&#62; struct has_trivial_assign;</div><div class="code_line">template &#60;class T&#62; struct has_trivial_destructor;</div><div class="code_line">template &#60;class T&#62; struct has_nothrow_constructor;</div><div class="code_line">template &#60;class T&#62; struct has_nothrow_copy;</div><div class="code_line">template &#60;class T&#62; struct has_nothrow_assign;</div><div class="code_line">template &#60;class T&#62; struct has_virtual_destructor;</div><div class="code_line">template &#60;class T&#62; struct is_signed;</div><div class="code_line">template &#60;class T&#62; struct is_unsigned;</div><div class="code_line">template &#60;class T&#62; struct alignment_of;</div><div class="code_line">template &#60;class T&#62; struct rank;</div><div class="code_line">template &#60;class T, unsigned I = 0&#62; struct extent;</div><div class="code_line">// type relations:</div><div class="code_line">template &#60;class T, class U&#62; struct is_same;</div><div class="code_line">template &#60;class Base, class Derived&#62; struct is_base_of;</div><div class="code_line">template &#60;class From, class To&#62; struct is_convertible;</div><div class="code_line">// const-volatile modifications:</div><div class="code_line">template &#60;class T&#62; struct remove_const;</div><div class="code_line">template &#60;class T&#62; struct remove_volatile;</div><div class="code_line">template &#60;class T&#62; struct remove_cv;</div><div class="code_line">template &#60;class T&#62; struct add_const;</div><div class="code_line">template &#60;class T&#62; struct add_volatile;</div><div class="code_line">template &#60;class T&#62; struct add_cv;</div><div class="code_line">// reference modifications:</div><div class="code_line">template &#60;class T&#62; struct remove_reference;</div><div class="code_line">template &#60;class T&#62; struct add_reference;</div><div class="code_line">// array modifications:</div><div class="code_line">template &#60;class T&#62; struct remove_extent;</div><div class="code_line">template &#60;class T&#62; struct remove_all_extents;</div><div class="code_line">// pointer modifications:</div><div class="code_line">template &#60;class T&#62; struct remove_pointer;</div><div class="code_line">template &#60;class T&#62; struct add_pointer;</div><div class="code_line">// other transformations:</div><div class="code_line">template &#60;std::size_t Len, std::size_t Align&#62; struct aligned_storage;</div></ol></div></div></div></div><br>
<br>
Характеристики типов - это такие шаблоны, которые позволяют узнать кое-что о типе T. Имеют широкое применение в шаблонном программировании.<br>
<br>
<hr><br>
<br>
<span class='tag-size' data-value='11' style='font-size:11pt;'><strong class='tag-b'><span class="tag-color tag-color-named" data-value="blue" style="color: blue"><span class='tag-u'>Random Number Generation</span></span></strong></span>(<a class='tag-url' href='http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2003/n1452.html' target='_blank'>n1452</a>)<br>
<br>
Старый добрый rand заменит целая библиотека. Это разумно т.к. используя rand случайных чисел добится сложно, а применяются они много где(игры, моделирование, тестирование, криптография и компьютерная безопасность).<br>
<ul class="tag-list">Введены концепции</li><li><strong class='tag-b'>Uniform random number generator</strong>.<br>
Представляет из себя функтор, каждый вызов которого возвращает очередное (псевдо)случайное число.</li><li><strong class='tag-b'>Pseudo-random number engine</strong>.<br>
Расщирение концепции Uniform random number generator для того, чтобы генератор можно было создавать, копировать и управлять им(seed, etc.).<br>
	<ul class="tag-list">Шаблонные классы, отвечающие концепции<br>
	</li><li>linear_congruential<br>
	</li><li>mersenne_twister<br>
	</li><li>subtract_with_carry<br>
	</li><li>subtract_with_carry_01<br>
	</li><li>discard_block</li></ul><br>
	<ul class="tag-list">Специализации шаблонных классов, отвечающих концепции<br>
	</li><li>minstd_rand0<br>
	</li><li>minstd_rand<br>
	</li><li>mt19937<br>
	</li><li>ranlux_base_01<br>
	</li><li>ranlux64_base_01<br>
	</li><li>ranlux3<br>
	</li><li>ranlux4<br>
	</li><li>ranlux3_01<br>
	</li><li>ranlux4_01</li></ul></li><li><strong class='tag-b'>Random distribution</strong>.<br>
Имеет смысл <a class='tag-url' href='http://ru.wikipedia.org/wiki/%D0%A0%D0%B0%D1%81%D0%BF%D1%80%D0%B5%D0%B4%D0%B5%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5_%D0%B2%D0%B5%D1%80%D0%BE%D1%8F%D1%82%D0%BD%D0%BE%D1%81%D1%82%D0%B5%D0%B9' target='_blank'>распределения</a>.<br>
Представляет из себя функтор, который на вход берёт объект, отвечающий концепции Uniform random number generator, на выход даёт распределение.<br>
Включённых в TR1 распределений(отвечающих концепции) много, список приводить смысла, думаю, не имеет.</li></ul><br>
<hr><br>
<br>
<span class='tag-size' data-value='11' style='font-size:11pt;'><strong class='tag-b'>Специальные математические функции</strong></span>(<a class='tag-url' href='http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2003/n1542.pdf' target='_blank'>n1542</a>)<br>
<br>
Теперь &lt;cmath&gt; обзавёлся специальными математическими ф-циями. Теперь, возможно, проще будет писать программы, занимающимися научными расчётами.<br>
Описывать этот пункт более подробно, думаю, смысла нету, тем более, что в высшей математике я смыслю мало :).<br>
<br>
<hr><br>
<br>
<span class='tag-size' data-value='11' style='font-size:11pt;'><strong class='tag-b'><span class="tag-color tag-color-named" data-value="blue" style="color: blue"><span class='tag-u'>Tuple</span></span></strong></span>(<a class='tag-url' href='http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2002/n1403.pdf' target='_blank'>n1403</a>)<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">// Header &#60;tuple&#62; synopsis</div><div class="code_line">&nbsp;</div><div class="code_line">// Class template tuple</div><div class="code_line">template &#60;</div><div class="code_line">&nbsp;&nbsp; &nbsp;class T1 = <span style='color:red'>unspecified</span> ,</div><div class="code_line">&nbsp;&nbsp; &nbsp;class T2 = <span style='color:red'>unspecified</span> ,</div><div class="code_line">&nbsp;&nbsp; &nbsp;...,</div><div class="code_line">&nbsp;&nbsp; &nbsp;class TM = <span style='color:red'>unspecified</span> &#62; class tuple;</div><div class="code_line">&nbsp;</div><div class="code_line">// Tuple creation functions</div><div class="code_line">const <span style='color:red'>unspecified</span> ignore;</div><div class="code_line">&nbsp;</div><div class="code_line">template&#60;class T1, class T2, ..., class TN&#62;</div><div class="code_line">tuple&#60;V1, V2, ..., VN&#62; make_tuple(const T1&amp;, const T2&amp; , ..., const TN&amp;);</div><div class="code_line">&nbsp;</div><div class="code_line">template&#60;class T1, class T2, ..., class TN&#62;</div><div class="code_line">tuple&#60;T1&amp;, T2&amp;, ..., TN&amp;&#62; tie(T1&amp;, T2&amp; , ..., TN&amp;);</div><div class="code_line">&nbsp;</div><div class="code_line">// Tuple helper classes</div><div class="code_line">template &#60;class T&#62; class tuple_size;</div><div class="code_line">template &#60;int I, class T&#62; class tuple_element;</div><div class="code_line">&nbsp;</div><div class="code_line">// Element access</div><div class="code_line">template &#60;int I, class T1, class T2, ..., class TN&#62;</div><div class="code_line"><span style='color:red'>RJ</span> get(tuple&#60;T1, T2, ..., TN&#62;&amp;);</div><div class="code_line">&nbsp;</div><div class="code_line">template &#60;int I, class T1, class T2, ..., class TN&#62;</div><div class="code_line"><span style='color:red'>PJ</span> get(const tuple&#60;T1, T2, ..., TN&#62;&amp;);</div><div class="code_line">&nbsp;</div><div class="code_line">// relational operators</div><div class="code_line">template&#60;class T1, class T2, ..., class TM, class U1, class U2, ..., class UM&#62;</div><div class="code_line">bool operator==(const tuple&#60;T1, T2, ..., TM&#62;&amp;, const tuple&#60;U1, U2, ..., UM&#62;&amp;);</div><div class="code_line">&nbsp;</div><div class="code_line">template&#60;class T1, class T2, ..., class TM, class U1, class U2, ..., class UM&#62;</div><div class="code_line">bool operator&#60;(const tuple&#60;T1, T2, ..., TM&#62;&amp;, const tuple&#60;U1, U2, ..., UM&#62;&amp;);</div><div class="code_line">&nbsp;</div><div class="code_line">template&#60;class T1, class T2, ..., class TM, class U1, class U2, ..., class UM&#62;</div><div class="code_line">bool operator!=(const tuple&#60;T1, T2, ..., TM&#62;&amp;, const tuple&#60;U1, U2, ..., UM&#62;&amp;);</div><div class="code_line">&nbsp;</div><div class="code_line">template&#60;class T1, class T2, ..., class TM, class U1, class U2, ..., class UM&#62;</div><div class="code_line">bool operator&#62;(const tuple&#60;T1, T2, ..., TM&#62;&amp;, const tuple&#60;U1, U2, ..., UM&#62;&amp;);</div><div class="code_line">&nbsp;</div><div class="code_line">template&#60;class T1, class T2, ..., class TM, class U1, class U2, ..., class UM&#62;</div><div class="code_line">bool operator&#60;=(const tuple&#60;T1, T2, ..., TM&#62;&amp;, const tuple&#60;U1, U2, ..., UM&#62;&amp;);</div><div class="code_line">&nbsp;</div><div class="code_line">template&#60;class T1, class T2, ..., class TM, class U1, class U2, ..., class UM&#62;</div><div class="code_line">bool operator&#62;=(const tuple&#60;T1, T2, ..., TM&#62;&amp;, const tuple&#60;U1, U2, ..., UM&#62;&amp;);</div></ol></div></div></div></div><br>
<br>
Tuple(англ. кортеж) - это std::pair только на произвольное количество элементов.<br>
<br>
Есть ф-ции make_tuple(аналог make_pair) и tie(аналог make_tuple, только все типы оборачиваются в reference_wrapper).<br>
<br>
Есть шаблоны для узнавания размера кортежа(tuple_size&lt; SomeTuple &gt;::value) и для узнавания N-ого типа в кортеже(tuple_element&lt; N, SomeTuple &gt;::type).<br>
<br>
Есть ф-ции для вытягивания N-ого элемента из кортежа(get&lt; N &gt;(someTupleInstance)).<br>
<br>
Есть ф-ции сравнения которые эквиваленты логическому И между результатами поэлементного сравнения.<br>
<br>
Кортежы CopyConstructible и Assignable, причём справа может стоять кортеж другого типа - главное, чтобы были соответствующие copy constructor(copy assignment operator) позволяющие поэлементно сконструировать копии(приравнять).<br>
<br>
У tuple есть конструктор копии и оператор присваивания от std::pair(только если tuple_size&lt;Tuple&gt;::value == 2).<br>
Также, шаблоны tuple_size, tuple_element и ф-ции get перегружены для случая с std::pair и std::array(см. ниже). std::array считаеться как кортеж из N элементов <em class='tag-i'>одинакового</em> типа.<br>
<br>
Замечу, что применения tuple, в отличии от std::pair не оганичиваются только аггрегированием нескольких объектов в один - их ещё можно использовать как списки типов(вместе с шаблонами tuple_size и tuple_element).<br>
<br>
<hr><br>
<br>
<span class='tag-size' data-value='11' style='font-size:11pt;'><strong class='tag-b'><span class="tag-color tag-color-named" data-value="blue" style="color: blue"><span class='tag-u'>Fixed Size Array</span></span></strong></span>(<a class='tag-url' href='http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2003/n1548.htm' target='_blank'>n1548</a>)<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">// Class template array</div><div class="code_line">template &#60;class T, size_t N &#62; struct array;</div><div class="code_line">&nbsp;</div><div class="code_line">// Array comparisons</div><div class="code_line">template &#60;class T, size_t N&#62; bool operator== (const array&#60;T,N&#62;&amp; x, const array&#60;T,N&#62;&amp; y);</div><div class="code_line">template &#60;class T, size_t N&#62; bool operator!= (const array&#60;T,N&#62;&amp; x, const array&#60;T,N&#62;&amp; y);</div><div class="code_line">template &#60;class T, size_t N&#62; bool operator&#60; (const array&#60;T,N&#62;&amp; x, const array&#60;T,N&#62;&amp; y);</div><div class="code_line">template &#60;class T, size_t N&#62; bool operator&#62; (const array&#60;T,N&#62;&amp; x, const array&#60;T,N&#62;&amp; y);</div><div class="code_line">template &#60;class T, size_t N&#62; bool operator&#60;= (const array&#60;T,N&#62;&amp; x, const array&#60;T,N&#62;&amp; y);</div><div class="code_line">template &#60;class T, size_t N&#62; bool operator&#62;= (const array&#60;T,N&#62;&amp; x, const array&#60;T,N&#62;&amp; y);</div></ol></div></div></div></div><br>
<br>
Представляет из себя обёртку для массивов фиксированной длины.<ul class="tag-list">Преимуществ много:</li><li>Как и обычные T[N] их можно инициализировать array&lt;int, 2&gt; = {1, 2}, использовать оператор[] и т.д.</li><li>Является STL-совместимым контейнером.(Sequence container).</li><li><ul class="tag-list">В отличии от обычных T[N]<br>
   </li><li>array&lt;T, N&gt; можно передавать в ф-ции(происходит копирование).<br>
   </li><li>у array&lt;T, N&gt; можно легко узнать его размер.<br>
   </li><li>проще использовать в STL-алгоритмах(из-за его STL-совместимости).</li></ul></li></ul><br>
<hr><br>
<br>
<span class='tag-size' data-value='11' style='font-size:11pt;'><strong class='tag-b'><span class="tag-color tag-color-named" data-value="blue" style="color: blue"><span class='tag-u'>Unordered associative containers</span></span></strong></span>(<a class='tag-url' href='http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2003/n1456.html' target='_blank'>n1456</a>)<br>
<br>
Элементы в обычных ассоциативных контейнерах из C++03(map, set, multimap, multiset) упорядочены по ключу.<br>
Далее речь пойдёт о неупорядоченных ассоциативных контейнерах(unordered_map, unordered_*). Принцип их работы заключается в том, что их ключи хэшируются и хранятся по принципу хэш таблицы.<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">// Hash function base template</div><div class="code_line">template &#60;class T&#62;</div><div class="code_line">struct hash : public std::unary_function&#60;T, std::size_t&#62;</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; &nbsp;std::size_t operator()(T val) const;</div><div class="code_line">};</div><div class="code_line">&nbsp;</div><div class="code_line">// Class template unordered_set</div><div class="code_line">template &#60;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;class Value,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;class Hash = hash&#60;Value&#62;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;class Pred = std::equal_to&#60;Value&#62;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;class Alloc = std::allocator&#60;Value&#62; &#62;</div><div class="code_line">&nbsp;&nbsp; &nbsp;class unordered_set;</div><div class="code_line">// Class template unordered_multiset</div><div class="code_line">template &#60;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;class Value,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;class Hash = hash&#60;Value&#62;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;class Pred = std::equal_to&#60;Value&#62;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;class Alloc = std::allocator&#60;Value&#62; &#62;</div><div class="code_line">&nbsp;&nbsp; &nbsp;class unordered_multiset;</div><div class="code_line">&nbsp;</div><div class="code_line">// Class template unordered_map</div><div class="code_line">template &#60;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;class Key,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;class T,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;class Hash = hash&#60;Key&#62;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;class Pred = std::equal_to&#60;Key&#62;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;class Alloc = std::allocator&#60;std::pair&#60;const Key, T&#62; &#62; &#62;</div><div class="code_line">&nbsp;&nbsp; &nbsp;class unordered_map;</div><div class="code_line">// Class template unordered_multimap</div><div class="code_line">template &#60;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;class Key,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;class T,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;class Hash = hash&#60;Key&#62;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;class Pred = std::equal_to&#60;Key&#62;,</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;class Alloc = std::allocator&#60;std::pair&#60;const Key, T&#62; &#62; &#62;</div><div class="code_line">&nbsp;&nbsp; &nbsp;class unordered_multimap;</div></ol></div></div></div></div><br>
<br>
Итак. Основой для хэширования является функтор hash. В TR1 определены специализации этого шаблона для всех cv-unqualified арифметических типов, для любых указателей(T *) и для string/wstring.<br>
<br>
В неупорядоченных ассоциативных контейнерах всё работает <em class='tag-i'>почти</em> точно так же как и у соответствующих контейнеров без префикса unordered.<br>
<br>
Зачем они нужны? Да затем же, зачем хэш-таблицы - для скорости.<br>
Возьмём ключ типа string - в случае поиска в обычном контейнере произойдёт  log2N сравнений. А если строки по 50 мб? Накладно. Развею ваши иллюзии(если таковые появились) - в худшем случае в хэш-контейнер пройзойдёт не меньше сравнений. Но для худшего случая нужно постараться, а в общем же случае - 1/2/3/мало сравнений при любом N :). Для ключей, у которых оператор сравнения является дорогой операцией - эти контейнеру просто незаменимы.<br>
<br>
<hr><br>
<br>
<span class='tag-size' data-value='11' style='font-size:11pt;'><strong class='tag-b'><span class="tag-color tag-color-named" data-value="blue" style="color: blue"><span class='tag-u'>Regular expressions</span></span></strong></span>(<a class='tag-url' href='http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2003/n1429.htm' target='_blank'>n1429</a>)<br>
<br>
<a class='tag-url' href='http://ru.wikipedia.org/wiki/%D0%A0%D0%B5%D0%B3%D1%83%D0%BB%D1%8F%D1%80%D0%BD%D1%8B%D0%B5_%D0%B2%D1%8B%D1%80%D0%B0%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F' target='_blank'>Регулярные выражения</a> - это удобный, мощный и лаконичный способ работы со строками(поиск/выделение фрагментов/замены фрагментов и т.п.). Они присутствуют во многих языках и стали чуть ли не промышленным стандартом(??) в этой области.<br>
<br>
Как сами регулярные выражения, так и часть из TR1, реализующая ф-циональность регулярных выражений достаточно обширны и нет возможности описать их здесь полностью. Описывать частично смысла не имеет. Могу лишь привести пример:<br>
<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">regex e(&quot;(\d{3,4})[- ]?(\d{4})[- ]?(\d{4})[- ]?(\d{4})&quot;);</div><div class="code_line">&nbsp;</div><div class="code_line">bool is_possible_card_number(const std::string&amp; input)</div><div class="code_line">{</div><div class="code_line">&nbsp;&nbsp; //</div><div class="code_line">&nbsp;&nbsp; // return false for partial match, true for full match, or throw for</div><div class="code_line">&nbsp;&nbsp; // impossible match based on what we have so far...</div><div class="code_line">&nbsp;&nbsp; match_results&#60;std::string::const_iterator&#62; what;</div><div class="code_line">&nbsp;&nbsp; if(0 == boost::regex_match(input, what, e, match_default | match_partial))</div><div class="code_line">&nbsp;&nbsp; {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;// the input so far could not possibly be valid so reject it:</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;throw std::runtime_error(&quot;Invalid data entered - this could not possibly be a valid card number&quot;);</div><div class="code_line">&nbsp;&nbsp; }</div><div class="code_line">&nbsp;&nbsp; // OK so far so good, but have we finished?</div><div class="code_line">&nbsp;&nbsp; if(what[0].matched)</div><div class="code_line">&nbsp;&nbsp; {</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;// excellent, we have a result:</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;return true;</div><div class="code_line">&nbsp;&nbsp; }</div><div class="code_line">&nbsp;&nbsp; // what we have so far is only a partial match...</div><div class="code_line">&nbsp;&nbsp; return false;</div><div class="code_line">}</div></ol></div></div></div></div><br>
<br>
<hr><br>
<br>
Что мы имеем в итоге?<br>
Стандартизация TR1 была начата в 2001 году, ещё до выхода С++03. В силу ли этой причины или в силу того, что комитет не собирался добавлять ни в язык ни в библиотеку ничего кардинально нового, но TR1 по содержанию своему очень жалок на первый взгляд(учитывая то, что реализация всего содержимого TR1 на момент его выпуска уже давно была в том же Boost). С другой стороны, все элементы TR1 можно реализовать с помощью стандартного С++ и никаких системно-специфичных вещей там нету, что, несомненно плюс. Ещё не могу не заметить, что не смотря на скудность своего содержания, TR1 представляет из себя 198 страниц формализованного текста, а это больше чем четверть того, что было в существовавшем на тот момент стандарте С++98.<br>
<br>
TR2 в сравнении с TR1 будет просто несравненно огромен. Чего там только не будет. Про TR2 в следующий раз :).<br>
<br>
И напоследок: <span class="tag-color tag-color-named" data-value="red" style="color: red"><strong class='tag-b'>не изобретайте велосипедов&copy;</strong></span>, по возможности используйте <em class='tag-i'>уже</em> стандартизованные средства.<br>
<br>
<hr><br>
<br>
Обсуждение, дополнения и коррективы приветствуются. Всем спасибо за внимание.]]></description>
        <author>archimed7592</author>
        <category>C/C++: Общие вопросы</category>
      </item>
	
      </channel>
      </rss>
	