Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
Разработка программного обеспечения

Appendices

Boost , The Boost C++ Libraries BoostBook Documentation Subset , Chapter 43. Boost.Xpressive

Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

PrevUpHomeNext

Version 2.1.0 6/12/2008

Новые особенности:

  • <skip()>примитив для статических регексов, что позволяет задавать части входной строки для игнорирования при сопоставлении регексов.
  • Диапазонный<regex_replace()>интерфейс алгоритма.
  • <regex_replace()>принимает объекты форматировщика и выражения форматировщика лямбда в дополнение к строкам формата.

Bugs Fixed:

  • Семантические действия в смотрящих вперед, смотрящих позади и независимых суб-выражениях выполняются охотно, а не вызывают крах.

Version 2.0.1 10/23/2007

Bugs Fixed:

  • <sub_match<>>Конструктор копирует сингулярный итератор, вызывая отладку.

Version 2.0.0, 10/12/2007

Новые особенности:

  • Семантические действия
  • Обычные утверждения
  • Названы захваты
  • Динамические грамматики regex
  • Рекурсивные динамические регексы с конструкцией<(?R)>
  • Поддержка поиска нехарактерных данных
  • Лучшие ошибки для недействительных статических регексов
  • Интерфейс алгоритма Regex на основе диапазона
  • <match_flag_type::format_perl>,<match_flag_type::format_sed>и<match_flag_type::format_all>
  • <operator+(std::string,sub_match<>)>и другие варианты
  • Версия 2 Regex traits get<tolower()>и<toupper()>

Bugs Fixed:

  • Устанавливает однотипные наборы, как<~(set='a')>работает.

Version 1.0.2, April 27, 2007

Bugs Fixed:

  • Обратные ссылки более девяти работ в качестве рекламы.

Это версия, которая поставляется как часть Boost 1.34.

Version 1.0.1, October 2, 2006

Bugs Fixed:

  • <match_results::position()>работает для вложенных результатов.

Version 1.0.0, March 16, 2006

Версия 1.0!

Version 0.9.6, August 19, 2005

Версия рецензируется для принятия в Boost. Обзор начался 8 сентября 2005 года. Xpressive был принят в Boost 28 сентября 2005 года.

Version 0.9.3, June 30, 2005

Новые особенности:

  • TR1-стиль regex_traits интерфейс
  • Повышение скорости
  • <syntax_option_type::ignore_white_space>

Version 0.9.0, September 2, 2004

Новые особенности:

  • Это вроде как работает.

Version 0.0.1, November 16, 2003

Объявление о нажатии:http://lists.boost.org/Archives/boost/2003/11/56312.php

Для xpressive 2.X запланированы следующие функции:

  • <syntax_option_type::collate>
  • Последовательность коллаций, такая как<[.a.]>
  • Классы эквивалентности<[=a=]>
  • Управление вложенными результатами генерации с<syntax_option_type::nosubs>и модификатором<nosubs()>для статического давления.

Вот некоторые особенности списка желаний. Вы или ваша компания должны рассмотреть возможность найма меня для их реализации.

  • Оптимизированный бэкэнд DFA для простого и быстрого регексинга.
  • Различные передние концы компилятора regex для базового, расширенного, awk, grep и egrep regex синтаксиса.
  • Тонкий контроль над динамическим синтаксисом регекса
  • Опциональная интеграция с ICU для полной поддержки Unicode.
  • Улучшенная поддержка локализации, возможно, как пользовательский аспект<std::locale>.

Поскольку многие пользователи Xpressive, вероятно, знакомы с библиотекойBoost.Regex, я был бы упущен, если бы не указал на некоторые важные различия между Xpressive иBoost.Regex. В частности:

  • <xpressive::basic_regex<>>— шаблон типа итератора, а не тип символа.
  • <xpressive::basic_regex<>>не может быть построен непосредственно из струны; скорее, вы должны использовать<basic_regex::compile()>или<regex_compiler<>>, чтобы построить объект регекса из струны.
  • <xpressive::basic_regex<>>не имеет<imbue()>функции члена; скорее,<imbue()>функция члена находится на<xpressive::regex_compiler<>>фабрике.
  • <boost::basic_regex<>>имеет подмножество членов<std::basic_string<>>.<xpressive::basic_regex<>>не является. Среди них:<assign()>,<operator[]()>,<max_size()>,<begin()>,<end()>,<size()>,<compare()>и<operator=(std::basic_string<>)>.
  • Другие функции, которые существуют в<boost::basic_regex<>>, но не существуют в<xpressive::basic_regex<>>:<set_expression()>,<get_allocator()>,<imbue()>,<getloc()>,<getflags()>и<str()>.
  • <xpressive::basic_regex<>>не имеет параметра шаблона RegexTraits. Настройка синтаксиса регекса и поведение локализации будут контролироваться<regex_compiler<>>и пользовательским аспектом регекса для<std::locale>.
  • <xpressive::basic_regex<>>и<xpressive::match_results<>>не имеют параметра шаблона Аллокатора. Это по дизайну.
  • <match_not_dot_null>и<match_not_dot_newline>перешли от<match_flag_type>к<syntax_option_type>, и они сменили названия на<not_dot_null>и<not_dot_newline>.
  • Не поддерживаются следующие<syntax_option_type>значения перечисления:<escape_in_lists>,<char_classes>,<intervals>,<limited_ops>,<newline_alt>,<bk_plus_qm>,<bk_parens>,<bk_refs>,<bk_vbar>,<failbit>,<literal>,<perlex>,<basic>,<extended>,<emacs>,<awk>,<grep>,<egrep>,<sed>,<JavaScript>,<JScript>.
  • Не поддерживаются следующие<match_flag_type>значения перечисления:<match_not_bob>,<match_not_eob>,<match_perl>,<match_posix>и<match_extra>.

Также в текущей реализации алгоритмы регекса в депрессивном режиме не будут обнаруживать патологическое поведение и прерывать, выбрасывая исключение. Вы должны писать эффективные шаблоны, которые не ведут себя патологически.

Показатели хпрессивности конкурентоспособны сBoost.Regex. Я запустил тесты производительности, сравнивающие статический, динамический иBoost.Regexна двух платформах: gcc (Cygwin) и Visual C++. Тесты включают короткие матчи и длительные поиски. Для обеих платформ xpressive отлично подходит для коротких матчей и примерно соответствуетBoost.Regexдля длинных поисков.

Как и во всех тестах, истинным тестом является то, как Xpressive работает свашимишаблонами,вашимвходом ивашейплатформой, поэтому, если производительность имеет значение в вашем приложении, лучше всего запустить свои собственные тесты.

Ниже приведены результаты сравнения производительности между:

  • статичный xpressive
  • Динамический xpressive
  • Boost.Regex

Test Specifications

Hardware:

гиперпоточность 3 ГГц Xeon с 1 Гб оперативной памяти

Operating System:

Windows XP Pro + Cygwin

Compiler:

GNU C++ версия 3.4.4 (Cygwin special)

C++ Standard Library:

GNU libstdc++ версия 3.4.4

Boost.Regex Version:

1.33+, BOOST_REGEX_USE_CPP_LOCALE, BOOST_REGEX_RECURSIVE

xpressive Version:

0.9.6a

Comparison 1: Short Matches

Следующие тесты оценивают время, необходимое для соответствия выражения входной строке. Для каждого результата верхнее число было нормализовано относительно самого быстрого времени, поэтому 1,0 так же хорош, как и получает. Нижнее число (в скобках) — фактическое время в секундах. Лучшее время было отмечено зеленым.

Short Matches
static xpressive dynamic xpressive Boost Text Expression
1

(8.79e & #8209;07s)
1.08

(9.54e & #8209;07s)
2.51

(2.2e‑06s)
100 - это строка ftp-ответа, содержащая строку сообщения <^([0-9]+)(\-| |$)(.*)$>
1.06

(1.07e & #8209;06s)
1

(1.01e & #8209;06s)
4.01

(4.06e & #8209;06s)
1234-5678-1234-456 <([[:digit:]]{4}[- ]){3}[[:digit:]]{3,4}>
1

(1.4e‑06s)
1.13

(1.58e & #8209;06s)
2.89

(4.05e‑06s)
john_maddock@compuserve.com <^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$>
1

(1.28e‑06s)
1.16

(1.49e & #8209;06s)
3.07

(3.94e & #8209;06s)
foo12@foo.edu <^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$>
1

(1.22e & #8209;06s)
1.2

(1.46e & #8209;06s)
3.22

(3.93e & #8209;06s)
bob.smith@foo.tv <^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$>
1.04

(8.64e & #8209;07s)
1

(8.34e & #8209;07s)
2.5

(2.09e‑06s)
EH10 2QQ <^[a-zA-Z]{1,2}[0-9][0-9A-Za-z]{0,1} {0,1}[0-9][A-Za-z]{2}$>
1.11

(9.09e & #8209;07s)
1

(8.19e & #8209;07s)
2.47

(2.03e & #8209;06s)
G1 1AA <^[a-zA-Z]{1,2}[0-9][0-9A-Za-z]{0,1} {0,1}[0-9][A-Za-z]{2}$>
1.12

(9.38e & #8209;07s)
1

(8.34e & #8209;07s)
2.5

(2.08e & #8209;06s)
SW1 1ZZ <^[a-zA-Z]{1,2}[0-9][0-9A-Za-z]{0,1} {0,1}[0-9][A-Za-z]{2}$>
1

(7.9e‑07s)
1.06

(8.34e & #8209;07s)
2.49

(1.96e & #8209;06s)
4/1/2001 <^[[:digit:]]{1,2}/[[:digit:]]{1,2}/[[:digit:]]{4}$>
1

(8.19e & #8209;07s)
1.04

(8.49e & #8209;07s)
2.4

(1.97e & #8209;06s)
12/12/2001 <^[[:digit:]]{1,2}/[[:digit:]]{1,2}/[[:digit:]]{4}$>
1.09

(8.95e & #8209;07s)
1

(8.19e & #8209;07s)
2.4

(1.96e‑06s)
123 <^[-+]?[[:digit:]]*\.?[[:digit:]]*$>
1.11

(8.79e & #8209;07s)
1

(7.9e‑07s)
2.57

(2.03e & #8209;06s)
+3.14159 <^[-+]?[[:digit:]]*\.?[[:digit:]]*$>
1.09

(8.94e & #8209;07s)
1

(8.19e & #8209;07s)
2.47

(2.03e & #8209;06s)
- 3.14159 <^[-+]?[[:digit:]]*\.?[[:digit:]]*$>

Comparison 2: Long Searches

Следующий тест измеряет время, чтобы найтивсесовпадения в длинном английском тексте. Текст представляет собойзаконченные работы Марка Твенаизпроекта Гутенберга. Текст длиной 19 Мб. Как указано выше, верхнее число - это нормированное время, а нижнее - фактическое время. Лучшее время – зеленое.

Long Searches
static xpressive dynamic xpressive Boost Expression
1

(0,0263s)
1

(0,0263s)
1.78

(0.0469)
<Twain>
1

(0,0234s)
1

(0,0234s)
1.79

(0.042s)
<Huck[[:alpha:]]+>
1.84

(1.26)
2.21

(1.51)
1

(0,687s)
<[[:alpha:]]+ing>
1.09

(0.192s)
2

(0,351)
1

(0.176s)
<^[^ ]*?Twain>
1.41

(0.08s)
1.21

(0.0684s)
1

(0,0566s)
<Tom|Sawyer|Huckleberry|Finn>
1.56

(0.195s)
1.12

(0.141)
1

(0.125s)
<(Tom|Sawyer|Huckleberry|Finn).{0,30}river|river.{0,30}(Tom|Sawyer|Huckleberry|Finn)>

Ниже приведены результаты сравнения производительности между:

  • статичный xpressive
  • Динамический xpressive
  • Boost.Regex

Test Specifications

Hardware:

гиперпоточность 3 ГГц Xeon с 1 Гб оперативной памяти

Operating System:

Windows XP Pro Pro

Compiler:

Visual C++ .NET 2003 (7.1)

C++ Standard Library:

Dinkumware, версия 313

Boost.Regex Version:

1.33+, BOOST_REGEX_USE_CPP_LOCALE, BOOST_REGEX_RECURSIVE

xpressive Version:

0.9.6a

Comparison 1: Short Matches

Следующие тесты оценивают время, необходимое для соответствия выражения входной строке. Для каждого результата верхнее число было нормализовано относительно самого быстрого времени, поэтому 1,0 так же хорош, как и получает. Нижнее число (в скобках) — фактическое время в секундах. Лучшее время было отмечено зеленым.

Short Matches
static xpressive dynamic xpressive Boost Text Expression
1

(3.2e‑007s)
1.37

(4.4e‑007s)
2.38

(7.6e & #8209;007s)
100 - это строка ftp-ответа, содержащая строку сообщения <^([0-9]+)(\-| |$)(.*)$>
1

(6.4e‑007s)
1.12

(7.15e & #8209;007s)
1.72

(1.1e‑006s)
1234-5678-1234-456 <([[:digit:]]{4}[- ]){3}[[:digit:]]{3,4}>
1

(9.82e & #8209;007s)
1.3

(1.28e‑006s)
1.61

(1.58e & #8209;006s)
john_maddock@compuserve.com <^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$>
1

(8.94e & #8209;007s)
1.3

(1.16e & #8209;006s)
1.7

(1.52e & #8209;006s)
foo12@foo.edu <^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$>
1

(9.09e & #8209;007s)
1.28

(1.16e & #8209;006s)
1.67

(1.52e & #8209;006s)
bob.smith@foo.tv <^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$>
1

(3.06e & #8209;007s)
1.07

(3.28e & #8209;007s)
1.95

(5.96e & #8209;007s)
EH10 2QQ <^[a-zA-Z]{1,2}[0-9][0-9A-Za-z]{0,1} {0,1}[0-9][A-Za-z]{2}$>
1

(3.13e & #8209;007s)
1.09

(3.42e & #8209;007s)
1.86

(5.81e & #8209;007s)
G1 1AA <^[a-zA-Z]{1,2}[0-9][0-9A-Za-z]{0,1} {0,1}[0-9][A-Za-z]{2}$>
1

(3.2e‑007s)
1.09

(3.5e‑007s)
1.86

(5.96e & #8209;007s)
SW1 1ZZ <^[a-zA-Z]{1,2}[0-9][0-9A-Za-z]{0,1} {0,1}[0-9][A-Za-z]{2}$>
1

(2.68e & #8209;007s)
1.22

(3.28e & #8209;007s)
2

(5.36e & #8209;007s)
4/1/2001 <^[[:digit:]]{1,2}/[[:digit:]]{1,2}/[[:digit:]]{4}$>
1

(2.76e‑007s)
1.16

(3.2e‑007s)
1.94

(5.36e & #8209;007s)
12/12/2001 <^[[:digit:]]{1,2}/[[:digit:]]{1,2}/[[:digit:]]{4}$>
1

(2.98e & #8209;007s)
1.03

(3.06e & #8209;007s)
1.85

(5.51e & #8209;007s)
123 <^[-+]?[[:digit:]]*\.?[[:digit:]]*$>
1

(3.2e‑007s)
1.12

(3.58e & #8209;007s)
1.81

(5.81e & #8209;007s)
+3.14159 <^[-+]?[[:digit:]]*\.?[[:digit:]]*$>
1

(3.28e & #8209;007s)
1.11

(3.65e & #8209;007s)
1.77

(5.81e & #8209;007s)
- 3.14159 <^[-+]?[[:digit:]]*\.?[[:digit:]]*$>

Comparison 2: Long Searches

Следующий тест измеряет время, чтобы найтивсесовпадения в длинном английском тексте. Текст представляет собойзаконченные работы Марка Твенаизпроекта Гутенберга. Текст длиной 19 Мб. Как указано выше, верхнее число - это нормированное время, а нижнее - фактическое время. Лучшее время – зеленое.

Long Searches
static xpressive dynamic xpressive Boost Expression
1

(0,019)
1

(0,019)
2.98

(0.0566s)
<Twain>
1

(0,0176s)
1

(0,0176s)
3.17

(0.0556s)
<Huck[[:alpha:]]+>
3.62

(1.78)
3.97

(1.95)
1

(0,492)
<[[:alpha:]]+ing>
2.32

(0.344)
3.06

(0.453s)
1

(0,148)
<^[^ ]*?Twain>
1

(0,0576s)
1.05

(0.0606s)
1.15

(0.0664s)
<Tom|Sawyer|Huckleberry|Finn>
1.24

(0.164s)
1.44

(0.191s)
1

(0,133)
<(Tom|Sawyer|Huckleberry|Finn).{0,30}river|river.{0,30}(Tom|Sawyer|Huckleberry|Finn)>

В xpressive объекты регекса могут относиться друг к другу и к себе по значению или по ссылке. Кроме того, они пересчитывают свои упомянутые регексы, чтобы сохранить их живыми. Это создает возможность циклического подсчета ссылок и повышает вероятность утечки памяти. Xpressive позволяет избежать утечек, используя тип, называемый<tracking_ptr<>>. Этот документ описывает на высоком уровне, как<tracking_ptr<>>работает.

Constraints

Наше решение должно соответствовать следующим дизайнерским ограничениям:

  • Никаких намеков: Все объекты, упомянутые прямо или косвенно, должны оставаться живыми до тех пор, пока необходимы ссылки.
  • Никаких утечек: все объекты в конечном итоге должны быть освобождены.
  • Без вмешательства пользователя: Решение не должно требовать от пользователей явного вызова некоторой рутины сбора циклов.
  • Уборка без броска: Фаза сбора, скорее всего, будет вызвана деструктором, поэтому он никогда не должен выбрасывать исключение ни при каких обстоятельствах.

Handle-Body Idiom

Чтобы использовать<tracking_ptr<>>, вы должны разделить свой тип на ручку и тело. В случае депрессии тип рукоятки называется<basic_regex<>>, а тело называется<regex_impl<>>. При этом он будет иметь 511 очков.

Тип тела должен наследоваться от<enable_reference_tracking<>>. Это дает организму структуры бухгалтерских данных, которые<tracking_ptr<>>будут использовать. В частности, он дает организму:

  1. <std::set<shared_ptr<body> >refs_>: совокупность тел, к которым относится это тело, и
  2. <std::set<weak_ptr<body> >deps_>: совокупность тел, относящихся к этому телу.

References and Dependencies

Мы называем (1) выше «ссылками» и (2) «зависимостями». Для понимания<tracking_ptr<>>важно признать, что набор ссылок включает как те объекты, которые упоминаются непосредственно, так и те, которые упоминаются косвенно (то есть через другую ссылку). То же самое можно сказать и о множестве зависимостей. Другими словами, каждое тело имеет счет обратной связи непосредственно с каждым другим телом, в котором оно нуждается.

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

Ссылки и зависимости пересекаются. Вот как это работает:

  1. Когда один объект приобретает другой в качестве ссылки, второй объект приобретает первый в качестве зависимости.
  2. Кроме того, первый объект получает все ссылки второго объекта, а второй объект приобретает все зависимости первого объекта.
  3. Когда объект получает новую ссылку, ссылка добавляется ко всем зависимым объектам.
  4. Когда объект улавливает новую зависимость, зависимость добавляется ко всем объектам.
  5. Объект никогда не может иметь себя в качестве зависимости. Объекты могут иметь себя в качестве ссылок, и часто делают.

Рассмотрим следующий код:

sregex expr;
{
    sregex group  = '(' >> by_ref(expr) >> ')';                 // (1)
    sregex fact   = +_d | group;                                // (2)
    sregex term   = fact >> *(('*' >> fact) | ('/' >> fact));   // (3)
    expr          = term >> *(('+' >> term) | ('-' >> term));   // (4)
}                                                               // (5)

Вот как распространяются ссылки и зависимости, строка за строкой:

выражение

последствия

1]<sregexgroup ='(' >>by_ref(expr)>> ')';>

<group: cnt=1 refs={expr} deps={}
expr: cnt=2 refs={} deps={group}
>

2]<sregexfact =+_d| group;>

<group: cnt=2 refs={expr} deps={fact}
expr: cnt=3 refs={} deps={group,fact}
fact: cnt=1 refs={expr,group} deps={}
>

3]<sregexterm =fact >>*(('*'>> fact) |('/'>> fact));>

<group: cnt=3 refs={expr} deps={fact,term}
expr: cnt=4 refs={} deps={group,fact,term}
fact: cnt=2 refs={expr,group} deps={term}
term: cnt=1 refs={expr,group,fact} deps={}
>

4]<expr= term>> *(('+' >>term)| ('-' >>term));>

<group: cnt=5 refs={expr,group,fact,term} deps={expr,fact,term}
expr: cnt=5 refs={expr,group,fact,term} deps={group,fact,term}
fact: cnt=5 refs={expr,group,fact,term} deps={expr,group,term}
term: cnt=5 refs={expr,group,fact,term} deps={expr,group,fact}
>

5]<}>

<expr: cnt=2 refs={expr,group,fact,term} deps={group,fact,term}>

Это показывает, как распространяются ссылки и зависимости при создании циклов объектов. После линии (4), которая замыкает цикл, каждый объект имеет счет на каждый другой объект, даже на себя. Так как же это не утечка? Читайте дальше.

Cycle Breaking

Теперь, когда тела имеют свои наборы ссылок и зависимостей, трудная часть сделана. Остается только решить, когда и где разорвать цикл. Это и есть работа<tracking_ptr<>>, которая является частью ручки.<tracking_ptr<>>содержит 2<shared_ptr>с. Первым, очевидно, является<shared_ptr<body>>— ссылка на тело, к которому относится эта рукоятка. Другой<shared_ptr>используется для разрыва цикла. Это гарантирует, что, когда все ручки тела выходят из сферы действия, набор ссылок на тело очищается.

Это говорит о том, что более одной ручки может относиться к телу. На самом деле<tracking_ptr<>>дает вам семантику копирования на записи — когда вы копируете ручку, тело делится. Это делает копии очень эффективными. В конце концов, все ручки для конкретного тела выходят из-под контроля. Когда это происходит, количество реф-счета в теле все еще может быть больше 0, потому что какое-то другое тело (или само это тело!) может ссылаться на него. Тем не менее, мы уверены, что обратный счет велосипедиста равен 0, потому что велосипедист живет только в ручках. Больше никаких ручек, больше никаких велосипедистов.

Что делает велосипедист? Напомним, что корпус имеет набор отсылок типа<std::set<shared_ptr<body>>>. Назовем этот тип «references_type». Цикл-брейкер — это<shared_ptr<references_type>>. Он использует пользовательский удалятель, который определяется следующим образом:

template<typename DerivedT>
struct reference_deleter
{
    void operator ()(std::set<shared_ptr<DerivedT> > *refs) const
    {
        refs->clear();
    }
};

Задача выключателя цикла состоит в том, чтобы гарантировать, что, когда последняя ручка тела уходит, набор ссылок на тело очищается. Вот так.

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

Немного сложнее понять, как это гарантирует отсутствие висячих ссылок. Представьте, что существует 3 тела: A, B и C. A относится к B, который относится к C. Теперь все ручки к B выходят из сферы действия, поэтому набор ссылок B очищен. Не означает ли это, что C удаляется, даже если он используется (косвенно) A? Это не так. Эта ситуация никогда не может произойти, потому что мы распространили ссылки и зависимости выше так, что A будет держать ссылку непосредственно на C в дополнение к B. Когда набор ссылок B очищается, никакие тела не удаляются, потому что они все еще используются A.

Future Work

Все эти<std::set>с и<shared_ptr>с и<weak_ptr>с! Очень неэффективно. Я использовал их, потому что они были удобны. Я мог бы сделать лучше.

Кроме того, некоторые объекты остаются дольше, чем нужно. Подумайте:

sregex b;
{
    sregex a = _;
    b = by_ref(a);
    b = _;
}
// a is still alive here!

Из-за распространения ссылок и зависимостей<std::set>ссылок может только расти. Он никогда не уменьшается, даже когда некоторые ссылки больше не нужны. Для кспрессионистов это не проблема. Графики ссылочных объектов обычно остаются небольшими и изолированными. Если бы кто-то попытался использовать<tracking_ptr<>>в качестве общего механизма сбора обратного счета-цикла, эта проблема должна была бы быть решена.


PrevUpHomeNext

Статья Appendices раздела The Boost C++ Libraries BoostBook Documentation Subset Chapter 43. Boost.Xpressive может быть полезна для разработчиков на c++ и boost.




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.



:: Главная :: Chapter 43. Boost.Xpressive ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-30 11:47:00
2025-05-19 17:22:00/0.013226985931396/0