Π§ΠΈΡ‚Π°ΠΉΡ‚Π΅ ΠΊΠ½ΠΈΠ³ΠΈ ΠΎΠ½Π»Π°ΠΉΠ½ Π½Π° Bookidrom.ru! БСсплатныС ΠΊΠ½ΠΈΠ³ΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠ»ΠΈΠΊΠ΅

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«Π‘Ρ‚Π°Π½Π΄Π°Ρ€Ρ‚Ρ‹ программирования Π½Π° Π‘++. 101 ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ ΠΈ рСкомСндация». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 49

Автор Π“Π΅Ρ€Π± Π‘Π°Ρ‚Ρ‚Π΅Ρ€

Π“Π»Π°Π²Π½ΠΎΠ΅ прСимущСство Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠΎΠ² ΠΈ шаблонов проСктирования Π² ΠΎΠ±Ρ‰Π΅ΠΌ случаС Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ΠΎΠ½ΠΈ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‚ Π½Π°ΠΌ Π³ΠΎΠ²ΠΎΡ€ΠΈΡ‚ΡŒ Π½Π° Π±ΠΎΠ»Π΅Π΅ высоком ΡƒΡ€ΠΎΠ²Π½Π΅ абстракции. Π’ соврСмСнном ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠΈ ΠΌΡ‹ Π½Π΅ Π³ΠΎΠ²ΠΎΡ€ΠΈΠΌ "ΠΏΡƒΡΡ‚ΡŒ нСсколько ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² слСдят Π·Π° ΠΎΠ΄Π½ΠΈΠΌ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠΌ ΠΈ ΠΏΠΎΠ»ΡƒΡ‡Π°ΡŽΡ‚ автоматичСскиС увСдомлСния ΠΏΡ€ΠΈ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΈ Π΅Π³ΠΎ состояния". ВмСсто этого ΠΌΡ‹ Π³ΠΎΠ²ΠΎΡ€ΠΈΠΌ просто ΠΎ "шаблонС проСктирования Observer". Аналогично, ΠΌΡ‹ Π³ΠΎΠ²ΠΎΡ€ΠΈΠΌ "Bridge", "Factory" ΠΈ "Visitor". ИспользованиС словаря шаблонов проСктирования позволяСт ΠΏΠΎΠ²Ρ‹ΡΠΈΡ‚ΡŒ ΡƒΡ€ΠΎΠ²Π΅Π½ΡŒ, ΡΡ„Ρ„Π΅ΠΊΡ‚ΠΈΠ²Π½ΠΎΡΡ‚ΡŒ ΠΈ ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎΡΡ‚ΡŒ нашСго обсуТдСния. Π’ΠΎΡ‡Π½ΠΎ Ρ‚Π°ΠΊ ΠΆΠ΅ ΠΏΡ€ΠΈ использовании Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠΎΠ² ΠΌΡ‹ Π½Π΅ Π³ΠΎΠ²ΠΎΡ€ΠΈΠΌ "выполняСм дСйствиС Π½Π°Π΄ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΌ элСмСнтом Π΄ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½Π° ΠΈ записываСм Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ Π² Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ мСсто"; вмСсто этого ΠΌΡ‹ Π³ΠΎΠ²ΠΎΡ€ΠΈΠΌ просто β€” transform. Аналогично, ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ ΡΠΊΠ°Π·Π°Ρ‚ΡŒ for_each, replace_if ΠΈ partition. Алгоритмы, ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΎ шаблонам проСктирования, самодокумСнтируСмы. "Π“ΠΎΠ»Ρ‹Π΅" Ρ†ΠΈΠΊΠ»Ρ‹ for ΠΈ while Π½ΠΈΡ‡Π΅Π³ΠΎ Π½Π΅ говорят ΠΎ Ρ‚ΠΎΠΌ, для Ρ‡Π΅Π³ΠΎ ΠΎΠ½ΠΈ ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½Ρ‹, ΠΈ Ρ‡ΠΈΡ‚Π°Ρ‚Π΅Π»ΡŽ приходится ΠΈΠ·ΡƒΡ‡Π°Ρ‚ΡŒ Ρ‚Π΅Π»Π° Ρ†ΠΈΠΊΠ»ΠΎΠ², Ρ‡Ρ‚ΠΎΠ±Ρ‹ Ρ€Π°ΡΡˆΠΈΡ„Ρ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΈΡ… сСмантику.

Алгоритмы ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ Π±ΠΎΠ»Π΅Π΅ ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½Ρ‹, Ρ‡Π΅ΠΌ Ρ†ΠΈΠΊΠ»Ρ‹. Π’ Ρ€Π°Π·Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅ΠΌΡ‹Ρ… ΡΠ°ΠΌΠΎΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΠ½ΠΎ Ρ†ΠΈΠΊΠ»Π°Ρ… Π»Π΅Π³ΠΊΠΎ Π΄ΠΎΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ ΠΎΡˆΠΈΠ±ΠΊΡƒ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Ρ‚Π°ΠΊΡƒΡŽ ΠΊΠ°ΠΊ использованиС Π½Π΅Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠ² (см. Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°Ρ†ΠΈΠΈ 83 ΠΈ 99); Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΡ‹ Π² Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ΅ ΠΎΡ‚Π»Π°ΠΆΠ΅Π½Ρ‹ Π½Π° ΠΏΡ€Π΅Π΄ΠΌΠ΅Ρ‚ использования Π½Π΅Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠ² ΠΈ Π΄Ρ€ΡƒΠ³ΠΈΡ… распространСнных ошибок.

И Π½Π°ΠΊΠΎΠ½Π΅Ρ†, Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΡ‹ Π·Π°Ρ‡Π°ΡΡ‚ΡƒΡŽ Ρ‚Π°ΠΊΠΆΠ΅ Π±ΠΎΠ»Π΅Π΅ эффСктивны, Ρ‡Π΅ΠΌ простыС Ρ†ΠΈΠΊΠ»Ρ‹ (см. [Sutter00] ΠΈ [Meyers01]). Π’ Π½ΠΈΡ… устранСны нСбольшиС нСэффСктивности, Ρ‚Π°ΠΊΠΈΠ΅ ΠΊΠ°ΠΊ ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½Ρ‹Π΅ вычислСния container.end()). НС ΠΌΠ΅Π½Π΅Π΅ Π²Π°ΠΆΠ½ΠΎ, Ρ‡Ρ‚ΠΎ стандартныС Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΡ‹, ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹Π΅ Π²Π°ΠΌΠΈ, Π±Ρ‹Π»ΠΈ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½Ρ‹ Ρ‚Π΅ΠΌΠΈ ΠΆΠ΅ программистами, ΠΊΡ‚ΠΎ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Ρ‹Π²Π°Π» ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹Π΅ Π²Π°ΠΌΠΈ стандартныС ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Ρ‹, ΠΈ понятно, Ρ‡Ρ‚ΠΎ ΠΈΡ… Π·Π½Π°Π½ΠΈΠ΅ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½Ρ‹Ρ… Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΉ позволяСт ΠΈΠΌ Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΡ‹ Π±ΠΎΠ»Π΅Π΅ эффСктивно, Ρ‡Π΅ΠΌ это смоТСтС ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Π²Ρ‹. Π’Π°ΠΆΠ½Π΅Π΅ всСго, ΠΎΠ΄Π½Π°ΠΊΠΎ, Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ ΠΌΠ½ΠΎΠ³ΠΈΠ΅ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΡ‹ ΠΈΠΌΠ΅ΡŽΡ‚ Π²Ρ‹ΡΠΎΠΊΠΎΠΈΠ½Ρ‚Π΅Π»Π»Π΅ΠΊΡ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹Π΅ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΡ‹ Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ смоТСм Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π² собствСнноручно Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚Π°Π½Π½ΠΎΠΌ ΠΊΠΎΠ΄Π΅ (Π½Π΅ считая случаСв, ΠΊΠΎΠ³Π΄Π° Π½Π°ΠΌ Π½Π΅ Π½ΡƒΠΆΠ½Π° Ρ‚Π° ΡΡ‚Π΅ΠΏΠ΅Π½ΡŒ обобщСнности, ΠΊΠΎΡ‚ΠΎΡ€ΡƒΡŽ ΠΏΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡΡŽΡ‚ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΡ‹). Π’ΠΎΠΎΠ±Ρ‰Π΅ говоря, Π±ΠΎΠ»Π΅Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΠ°Ρ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° всСгда оказываСтся Π»ΡƒΡ‡ΡˆΠ΅ ΠΎΡ‚Π»Π°ΠΆΠ΅Π½Π½ΠΎΠΉ ΠΈ Π±ΠΎΠ»Π΅Π΅ эффСктивной просто ΠΏΠΎΡ‚ΠΎΠΌΡƒ, Ρ‡Ρ‚ΠΎ Ρƒ Π½Π΅Π΅ большС ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ. Вряд Π»ΠΈ Π²Ρ‹ Π½Π°ΠΉΠ΄Π΅Ρ‚Π΅ ΠΈ смоТСтС ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π² своСй ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΡƒ, Π½Π°ΡΡ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΆΠ΅ ΡˆΠΈΡ€ΠΎΠΊΠΎ ΠΏΡ€ΠΈΠΌΠ΅Π½ΡΠ΅ΠΌΡƒΡŽ, ΠΊΠ°ΠΊ ΠΈ рСализация вашСй стандартной Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ. Π’ΠΎΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ΡΡŒ Сю. Алгоритмы STL ΡƒΠΆΠ΅ написаны β€” Ρ‚Π°ΠΊ ΠΏΠΎΡ‡Π΅ΠΌΡƒ Π±Ρ‹ Π½Π΅ Π²ΠΎΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ ΠΈΠΌΠΈ?

ΠŸΠΎΠ΄ΡƒΠΌΠ°ΠΉΡ‚Π΅ ΠΎΠ± использовании лямбда-Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ [Boost]. Лямбда-Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²Π»ΡΡŽΡ‚ собой Π²Π°ΠΆΠ½Ρ‹ΠΉ инструмСнт, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ позволяСт ΡΠΏΡ€Π°Π²ΠΈΡ‚ΡŒΡΡ с основным нСдостатком Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠΎΠ², Π° ΠΈΠΌΠ΅Π½Π½ΠΎ с ΡƒΠ΄ΠΎΠ±ΠΎΡ‡ΠΈΡ‚Π°Π΅ΠΌΠΎΡΡ‚ΡŒΡŽ. Π‘Π΅Π· ΠΈΡ… примСнСния Π²Ρ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π»ΠΈΠ±ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ (Π½ΠΎ Ρ‚ΠΎΠ³Π΄Π° Ρ‚Π΅Π»Π° Π΄Π°ΠΆΠ΅ простых Ρ†ΠΈΠΊΠ»ΠΎΠ² находятся Π² ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠΌ мСстС, Π΄Π°Π»Π΅ΠΊΠΎ ΠΎΡ‚ Ρ‚ΠΎΡ‡ΠΊΠΈ Π²Ρ‹Π·ΠΎΠ²Π°), Π»ΠΈΠ±ΠΎ стандартныС связыватСли ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ Π½Π°ΠΏΠΎΠ΄ΠΎΠ±ΠΈΠ΅ bind2nd ΠΈ plus (достаточно Π·Π°ΠΏΡƒΡ‚Π°Π½Π½Ρ‹Π΅, слоТныС ΠΈ ΡƒΡ‚ΠΎΠΌΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ Π² использовании).

ΠŸΡ€ΠΈΠΌΠ΅Ρ€Ρ‹

Π’ΠΎΡ‚ Π΄Π²Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°, Π°Π΄Π°ΠΏΡ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Ρ… ΠΈΠ· [Meyers01].

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ 1. ΠŸΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Π½ΠΈΠ΅ deque. ПослС Ρ‚ΠΎΠ³ΠΎ ΠΊΠ°ΠΊ Π±Ρ‹Π»ΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΎ нСсколько Π½Π΅ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½Ρ‹Ρ… ΠΈΡ‚Π΅Ρ€Π°Ρ†ΠΈΠΉ ΠΈΠ·-Π·Π° Π½Π΅Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠ² (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, см. Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°Ρ†ΠΈΡŽ 83), ΠΌΡ‹ ΠΏΡ€ΠΈΡˆΠ»ΠΈ ΠΊ ΠΎΠΊΠΎΠ½Ρ‡Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠΉ вСрсии Ρ†ΠΈΠΊΠ»Π° для прибавлСния 41 ΠΊ ΠΊΠ°ΠΆΠ΄ΠΎΠΌΡƒ элСмСнту массива Π΄Π°Π½Π½Ρ‹Ρ… Ρ‚ΠΈΠΏΠ° doublΠ΅ ΠΈ помСщСния Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π° Π² Π΄Π΅ΠΊ deque<doublΠ΅>:

deque<double>::iterator current = d.begin();

for (size_t i =0; i < max; ++i) {

 // БохраняСм current Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΌ

 current = d.insert(current, data[i] + 41);

 ++current; // Π£Π²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅ΠΌ Π΅Π³ΠΎ, ΠΊΠΎΠ³Π΄Π° это

}           // становится бСзопасным

Π’Ρ‹Π·ΠΎΠ² Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠ° позволяСт Π»Π΅Π³ΠΊΠΎ ΠΎΠ±ΠΎΠΉΡ‚ΠΈ всС Π»ΠΎΠ²ΡƒΡˆΠΊΠΈ Π² этом ΠΊΠΎΠ΄Π΅:

transform(

 data.begin(), data.end(),    // ΠšΠΎΠΏΠΈΡ€ΡƒΠ΅ΠΌ элСмСнты

 data inserter(d, d.begin()), // Π² d с Π½Π°Ρ‡Π°Π»Π° ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π°,

 bind2nd(plus<double>(),41)); // добавляя ΠΊ ΠΊΠ°ΠΆΠ΄ΠΎΠΌΡƒ 41

Π’ΠΏΡ€ΠΎΡ‡Π΅ΠΌ, bind2nd ΠΈ plus достаточно Π½Π΅ΡƒΠ΄ΠΎΠ±Π½Ρ‹. ΠžΡ‚ΠΊΡ€ΠΎΠ²Π΅Π½Π½ΠΎ говоря, Π² Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ ΠΈΡ… ΠΌΠ°Π»ΠΎ ΠΊΡ‚ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚, ΠΈ связано это Π² ΠΏΠ΅Ρ€Π²ΡƒΡŽ ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ с ΠΏΠ»ΠΎΡ…ΠΎΠΉ ΡƒΠ΄ΠΎΠ±ΠΎΡ‡ΠΈΡ‚Π°Π΅ΠΌΠΎΡΡ‚ΡŒΡŽ Ρ‚Π°ΠΊΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π° (см. Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°Ρ†ΠΈΡŽ 6).

ΠŸΡ€ΠΈ использовании лямбда-Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΡŽΡ‰ΠΈΡ… для нас Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹, ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ совсСм простой ΠΊΠΎΠ΄:

transform(data, data+max, inserter(d,d.begin()), _1 + 41);

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ 2. Найти ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ элСмСнт ΠΌΠ΅ΠΆΠ΄Ρƒ x ΠΈ Ρƒ. Рассмотрим простой Ρ†ΠΈΠΊΠ», ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ выполняСт поиск Π² vector<int> v ΠΏΠ΅Ρ€Π²ΠΎΠ³ΠΎ элСмСнта, Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ находится ΠΌΠ΅ΠΆΠ΄Ρƒ x ΠΈ y. Он вычисляСт ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ Π»ΠΈΠ±ΠΎ Π½Π° Π½Π°ΠΉΠ΄Π΅Π½Π½Ρ‹ΠΉ элСмСнт, Π»ΠΈΠ±ΠΎ Π½Π° v.end():

vector<int>::iterator i = v.begin();

for (; i != v.end(); ++i)

 if (*i > x && *i < y) break;

Π’Ρ‹Π·ΠΎΠ² Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠ° достаточно ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ°Ρ‚ΠΈΡ‡Π΅Π½. ΠŸΡ€ΠΈ отсутствии лямбда-Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ Ρƒ нас Π΅ΡΡ‚ΡŒ Π΄Π²Π° Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Π° β€” написаниС собствСнного Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° ΠΈΠ»ΠΈ использованиС стандартных связыватСлСй. Π£Π²Ρ‹, Π² послСднСм случаС ΠΌΡ‹ Π½Π΅ ΠΌΠΎΠΆΠ΅ΠΌ ΠΎΠ±ΠΎΠΉΡ‚ΠΈΡΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ стандартными связыватСлями ΠΈ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ нСстандартный (хотя ΠΈ достаточно распространСнный) Π°Π΄Π°ΠΏΡ‚Π΅Ρ€ compose2, Π½ΠΎ Π΄Π°ΠΆΠ΅ Π² этом случаС ΠΊΠΎΠ΄ получаСтся ΡΠΎΠ²Π΅Ρ€ΡˆΠ΅Π½Π½ΠΎ нСпонятным, Ρ‚Π°ΠΊ Ρ‡Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠΉ ΠΊΠΎΠ΄ Π½Π° ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠ΅ Π½ΠΈΠΊΡ‚ΠΎ просто Π½Π΅ Π½Π°ΠΏΠΈΡˆΠ΅Ρ‚:

vector<int>::iterator i =

 find_if(v.begin(), v.end(),

 compose2(logical_and<bool>(),

 bind2nd(greater<int>(), x), bind2nd(less<int>(), y)));

Π”Ρ€ΡƒΠ³ΠΎΠΉ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚, Π° ΠΈΠΌΠ΅Π½Π½ΠΎ β€” написаниС собствСнного Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° β€” достаточно ТизнСспособСн. Он достаточно Ρ…ΠΎΡ€ΠΎΡˆΠΎ выглядит Π² Ρ‚ΠΎΡ‡ΠΊΠ΅ Π²Ρ‹Π·ΠΎΠ²Π°, Π° Π³Π»Π°Π²Π½Ρ‹ΠΉ Π΅Π³ΠΎ нСдостаток— Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎΡΡ‚ΡŒ написания Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° BetweenValues, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π²ΠΈΠ·ΡƒΠ°Π»ΡŒΠ½ΠΎ удаляСт Π»ΠΎΠ³ΠΈΠΊΡƒ ΠΈΠ· Ρ‚ΠΎΡ‡ΠΊΠΈ Π²Ρ‹Π·ΠΎΠ²Π°:

template<typename T>

class BetweenValues : public unary_function<T, bool> {

public:

 BetweenValues(const T& low, const T& high)

  : low_(low), high_(high) { }

 bool operator()(const T& val) const

  { return val > low_ && val < high_; }

private:

 T low_, high_;

};


vector<int>::iterator i =

 find_if( v.begin(), v.end(), BetweenValues<int>(x, y));

ΠŸΡ€ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠΈ лямбда-Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ просто:

vector<int>::iterator i =

 find_if(v.begin(), v.end(), _1 > x && _1 < y);

Π˜ΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ

ΠŸΡ€ΠΈ использовании Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹Ρ… ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² Ρ‚Π΅Π»ΠΎ Ρ†ΠΈΠΊΠ»Π° оказываСтся Ρ€Π°Π·ΠΌΠ΅Ρ‰Π΅Π½ΠΎ Π² Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ мСстС, ΡƒΠ΄Π°Π»Π΅Π½Π½ΠΎΠΌ ΠΎΡ‚ Ρ‚ΠΎΡ‡ΠΊΠΈ Π²Ρ‹Π·ΠΎΠ²Π°, Ρ‡Ρ‚ΠΎ затрудняСт Ρ‡Ρ‚Π΅Π½ΠΈΠ΅ исходного тСкста. (ИспользованиС простых ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² со стандартными ΠΈ нСстандартными связыватСлями прСдставляСтся нСрСалистичным.)

Лямбда-Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ [Boost] Ρ€Π΅ΡˆΠ°ΡŽΡ‚ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡƒ ΠΈ Π½Π°Π΄Π΅ΠΆΠ½ΠΎ Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚ Π½Π° соврСмСнных компиляторах, Π½ΠΎ ΠΎΠ½ΠΈ Π½Π΅ годятся для Π±ΠΎΠ»Π΅Π΅ старых компиляторов ΠΈ ΠΌΠΎΠ³ΡƒΡ‚ Π²Ρ‹Π΄Π°Π²Π°Ρ‚ΡŒ большиС Π·Π°ΠΏΡƒΡ‚Π°Π½Π½Ρ‹Π΅ сообщСния ΠΎΠ± ΠΎΡˆΠΈΠ±ΠΊΠ°Ρ… ΠΏΡ€ΠΈ Π½Π΅ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎΠΌ использовании. Π’Ρ‹Π·ΠΎΠ² ΠΆΠ΅ ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½Ρ‹Ρ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, Π²ΠΊΠ»ΡŽΡ‡Π°Ρ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ-Ρ‡Π»Π΅Π½Ρ‹, всС Ρ€Π°Π²Π½ΠΎ Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ синтаксиса с использованиСм связыватСлСй.

Бсылки

[Allison98] Β§15 β€’ [Austern99] Β§11-13 β€’ [Boost] Lambda library β€’ [McConnell93] Β§15 β€’ [Meyers01] Β§43 β€’ [Musser01] Β§11 β€’ [Stroustrup00] Β§6.1.8, Β§18.5.1 β€’ [Sutter00] Β§7

85. ΠŸΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ΡΡŒ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½Ρ‹ΠΌ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠΎΠΌ поиска

РСзюмС

Данная рСкомСндация ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΠΌΠ° ΠΊ поиску ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ³ΠΎ значСния Π² Π΄ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½Π΅. ΠŸΡ€ΠΈ поискС Π² нСотсортированном Π΄ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΡ‹ find/find_if ΠΈΠ»ΠΈ count/count_if. Для поиска Π² отсортированном Π΄ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½Π΅ Π²Ρ‹Π±Π΅Ρ€ΠΈΡ‚Π΅ lower_bound, upper_bound, equal_range ΠΈΠ»ΠΈ (Ρ€Π΅ΠΆΠ΅) binary_search. (Π’ΠΎΠΏΡ€Π΅ΠΊΠΈ своСму ΠΈΠΌΠ΅Π½ΠΈ, binary_search ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ β€” Π½Π΅Π²Π΅Ρ€Π½Ρ‹ΠΉ Π²Ρ‹Π±ΠΎΡ€.)

ΠžΠ±ΡΡƒΠΆΠ΄Π΅Π½ΠΈΠ΅

Π’ случаС нСотсортированных Π΄ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½ΠΎΠ², find/find_if ΠΈ count/count_if ΠΌΠΎΠ³ΡƒΡ‚ Π·Π° Π»ΠΈΠ½Π΅ΠΉΠ½ΠΎΠ΅ врСмя ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ, находится Π»ΠΈ Π΄Π°Π½Π½Ρ‹ΠΉ элСмСнт Π² Π΄ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½Π΅, ΠΈ Ссли Π΄Π°, Ρ‚ΠΎ Π³Π΄Π΅ ΠΈΠΌΠ΅Π½Π½ΠΎ. Π—Π°ΠΌΠ΅Ρ‚ΠΈΠΌ, Ρ‡Ρ‚ΠΎ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΡ‹ find/find_if ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ Π±ΠΎΠ»Π΅Π΅ эффСктивны, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΌΠΎΠ³ΡƒΡ‚ Π·Π°Π²Π΅Ρ€ΡˆΠΈΡ‚ΡŒ поиск, ΠΊΠ°ΠΊ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ искомый элСмСнт оказываСтся Π½Π°ΠΉΠ΄Π΅Π½.

Π’ случаС сортированных Π΄ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½ΠΎΠ² Π»ΡƒΡ‡ΡˆΠ΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΡ‹ Π±ΠΈΠ½Π°Ρ€Π½ΠΎΠ³ΠΎ поиска β€” binary_search, lower_bound, upper_bound ΠΈ equal_range, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΈΠΌΠ΅ΡŽΡ‚ логарифмичСскоС врСмя Ρ€Π°Π±ΠΎΡ‚Ρ‹. Π£Π²Ρ‹, нСсмотря Π½Π° своС красивоС имя, binary_search практичСски всСгда бСсполСзСн, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ всСго лишь Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ Ρ‚ΠΈΠΏΠ° bool, ΡƒΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‰Π΅Π΅, Π½Π°ΠΉΠ΄Π΅Π½ искомый элСмСнт ΠΈΠ»ΠΈ Π½Π΅Ρ‚. ΠžΠ±Ρ‹Ρ‡Π½ΠΎ Π²Π°ΠΌ трСбуСтся Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ lower_bound ΠΈΠ»ΠΈ upper_bound, ΠΈΠ»ΠΈ equal_range, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π²Ρ‹Π΄Π°Π΅Ρ‚ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹ ΠΎΠ±ΠΎΠΈΡ… Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠΎΠ² β€” ΠΈ lower_bound, ΠΈ upper_bound (ΠΈ Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ Π² Π΄Π²Π° Ρ€Π°Π·Π° большС Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ).

Алгоритм lower_bound Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€, ΡƒΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‰ΠΈΠΉ Π½Π° ΠΏΠ΅Ρ€Π²Ρ‹ΠΉ подходящий элСмСнт (Ссли Ρ‚Π°ΠΊΠΎΠ²ΠΎΠΉ имССтся) ΠΈΠ»ΠΈ Π½Π° ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ, Π³Π΄Π΅ ΠΎΠ½ ΠΌΠΎΠ³ Π±Ρ‹ Π±Ρ‹Ρ‚ΡŒ (Ссли Ρ‚Π°ΠΊΠΎΠ³ΠΎ элСмСнта Π½Π΅Ρ‚); послСднСС ΠΏΠΎΠ»Π΅Π·Π½ΠΎ для поиска Π²Π΅Ρ€Π½ΠΎΠ³ΠΎ мСста для вставки Π½ΠΎΠ²Ρ‹Ρ… Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ Π² ΠΎΡ‚ΡΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½ΡƒΡŽ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ. Алгоритм upper_bound Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΈΡ‚Π΅Ρ€Π°Ρ‚ΠΎΡ€, ΡƒΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‰ΠΈΠΉ Π½Π° элСмСнт, ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ Π·Π° послСдним Π½Π°ΠΉΠ΄Π΅Π½Π½Ρ‹ΠΌ элСмСнтом (Ссли Ρ‚Π°ΠΊΠΎΠ²ΠΎΠΉ имССтся), Ρ‚.Π΅. Π½Π° ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ, ΠΊΡƒΠ΄Π° ΠΌΠΎΠΆΠ½ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ эквивалСнтный элСмСнт; это ΠΏΠΎΠ»Π΅Π·Π½ΠΎ ΠΏΡ€ΠΈ поискС ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½ΠΎΠ³ΠΎ мСста для вставки Π½ΠΎΠ²Ρ‹Ρ… Π·Π½Π°Ρ‡Π΅Π½ΠΈΠΉ Π² ΠΎΡ‚ΡΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½ΡƒΡŽ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Ρ‚ΡŒ ΡƒΠΏΠΎΡ€ΡΠ΄ΠΎΡ‡Π΅Π½Π½ΠΎΡΡ‚ΡŒ, ΠΏΡ€ΠΈ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ Ρ€Π°Π²Π½Ρ‹Π΅ элСмСнты Ρ€Π°ΡΠΏΠΎΠ»Π°Π³Π°ΡŽΡ‚ΡΡ Π² ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ Π² порядкС ΠΈΡ… вставки.