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

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

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

β€’ ΠŸΡ€Π΅Π΄ΠΈΠΊΠ°Ρ‚Ρ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ Π² ΠΏΡ€Π΅Π΄ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠΌ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠΌ порядкС. Π’ ΠΎΠ±Ρ‰Π΅ΠΌ случаС стандартныС Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΡ‹ Π½Π΅ Π΄Π°ΡŽΡ‚ Π½ΠΈΠΊΠ°ΠΊΠΎΠΉ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΠΈ ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ порядка примСнСния ΠΏΡ€Π΅Π΄ΠΈΠΊΠ°Ρ‚ΠΎΠ² ΠΊ элСмСнтам Π΄ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½Π°. ΠŸΡ€ΠΈ отсутствии Π³Π°Ρ€Π°Π½Ρ‚ΠΈΠΉ ΠΏΠΎ ΠΏΠΎΠ²ΠΎΠ΄Ρƒ порядка ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ элСмСнтов, опСрация Π½Π°ΠΏΠΎΠ΄ΠΎΠ±ΠΈΠ΅ "ΠΏΠΎΠΌΠ΅Ρ‚ΠΈΡ‚ΡŒ Ρ‚Ρ€Π΅Ρ‚ΠΈΠΉ элСмСнт" (см. ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρ‹) ΠΈΠΌΠ΅Π΅Ρ‚ ΠΌΠ°Π»ΠΎ смысла, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Π½Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΎ, ΠΊΠ°ΠΊΠΎΠΉ ΠΈΠΌΠ΅Π½Π½ΠΎ элСмСнт Π±ΡƒΠ΄Π΅Ρ‚ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π°Π½ Ρ‚Ρ€Π΅Ρ‚ΡŒΠΈΠΌ.

ΠŸΠ΅Ρ€Π²ΠΎΠ΅ условиС ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠ±ΠΎΠΉΡ‚ΠΈ, написав ΠΏΡ€Π΅Π΄ΠΈΠΊΠ°Ρ‚ с использованиСм счСтчика ссылок. Π­Ρ‚ΠΎΡ‚ ΠΌΠ΅Ρ‚ΠΎΠ΄ Ρ€Π΅ΡˆΠ°Π΅Ρ‚ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡƒ копирования ΠΏΡ€Π΅Π΄ΠΈΠΊΠ°Ρ‚ΠΎΠ², ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Π² Ρ‚Π°ΠΊΠΎΠΌ случаС ΠΏΡ€Π΅Π΄ΠΈΠΊΠ°Ρ‚Ρ‹ ΠΌΠΎΠ³ΡƒΡ‚ бСзопасно ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒΡΡ Π±Π΅Π· измСнСния ΠΈΡ… сСмантики ΠΏΡ€ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠΈ ΠΊ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌ (см. [Sutter02]). Однако ΠΎΠ±ΠΎΠΉΡ‚ΠΈ Π²Ρ‚ΠΎΡ€ΠΎΠ΅ условиС оказываСтся Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ.

ВсСгда ΠΎΠ±ΡŠΡΠ²Π»ΡΠΉΡ‚Π΅ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ ΠΏΡ€Π΅Π΄ΠΈΠΊΠ°Ρ‚Π° operator() ΠΊΠ°ΠΊ ΠΊΠΎΠ½ΡΡ‚Π°Π½Ρ‚Π½ΡƒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ-Ρ‡Π»Π΅Π½, Ρ‡Ρ‚ΠΎΠ±Ρ‹ компилятор ΠΌΠΎΠ³ ΠΏΠΎΠΌΠΎΡ‡ΡŒ Π²Π°ΠΌ ΠΈΠ·Π±Π΅ΠΆΠ°Ρ‚ΡŒ нСприятностСй, выводя сообщСниС ΠΎΠ± ошибкС ΠΏΡ€ΠΈ ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠ°Ρ… ΠΈΠ·ΠΌΠ΅Π½ΠΈΡ‚ΡŒ Π»ΡŽΠ±Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅-Ρ‡Π»Π΅Π½Ρ‹, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ Ρƒ ΠΏΡ€Π΅Π΄ΠΈΠΊΠ°Ρ‚Π°. Π­Ρ‚ΠΎ Π½Π΅ позволяСт ΠΏΡ€Π΅ΡΠ΅Ρ‡ΡŒ всС злоупотрСблСния, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, доступ ΠΊ Π³Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹ΠΌ Π΄Π°Π½Π½Ρ‹ΠΌ, Π½ΠΎ, ΠΏΠΎ ΠΊΡ€Π°ΠΉΠ½Π΅ΠΉ ΠΌΠ΅Ρ€Π΅, ΠΏΠΎΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΠ·Π±Π΅ΠΆΠ°Ρ‚ΡŒ Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ распространСнных ошибок.

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

ΠŸΡ€ΠΈΠΌΠ΅Ρ€. FlagNth. ΠŸΠ΅Ρ€Π΅Π΄ Π²Π°ΠΌΠΈ классичСский ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΈΠ· [Sutter02], Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ выполняСтся ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠ° ΡƒΠ΄Π°Π»ΠΈΡ‚ΡŒ Ρ‚Ρ€Π΅Ρ‚ΠΈΠΉ элСмСнт ΠΈΠ· ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π° v.

class FlagNth {

public:

 FlagNth(size_t n) : current_(0), n_(n) { }


 // Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ true Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΏΡ€ΠΈ Ρ‚Ρ€Π΅Ρ‚ΡŒΠ΅ΠΌ Π²Ρ‹Π·ΠΎΠ²Π΅

 template<typename T>

 bool operator()(const T&)     // ΠŸΠ»ΠΎΡ…ΠΎ: нСконстантная

  { return ++current_ == n_; } // функция

private:

 size_t current_, n_;

};


// ... ΠΏΠΎΠ·ΠΆΠ΅ ...

v.erase(remove_if(v.begin(), v.end(), FlagNth(3)));

Π£Π²Ρ‹, Π½Π΅Ρ‚ Π½ΠΈΠΊΠ°ΠΊΠΎΠΉ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΠΈ, Ρ‡Ρ‚ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ ΡƒΠ΄Π°Π»Π΅Π½ ΠΈΠΌΠ΅Π½Π½ΠΎ Ρ‚Ρ€Π΅Ρ‚ΠΈΠΉ элСмСнт Π’ Π±ΠΎΠ»ΡŒΡˆΠΈΠ½ΡΡ‚Π²Π΅ Ρ€Π΅Π°Π»ΡŒΠ½Ρ‹Ρ… Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΉ STL ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½Ρ‹ΠΉ ΠΊΠΎΠ΄ наряду с Ρ‚Ρ€Π΅Ρ‚ΡŒΠΈΠΌ ΡƒΠ΄Π°Π»ΠΈΡ‚ ΠΈ ΡˆΠ΅ΡΡ‚ΠΎΠΉ элСмСнт. ΠŸΠΎΡ‡Π΅ΠΌΡƒ? ΠŸΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ remove_if ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ рСализуСтся с использованиСм find_if ΠΈ remove_copy_if, ΠΈ копия ΠΏΡ€Π΅Π΄ΠΈΠΊΠ°Ρ‚Π° пСрСдаСтся ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΈΠ· этих Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ.

ΠšΠΎΠ½Ρ†Π΅ΠΏΡ‚ΡƒΠ°Π»ΡŒΠ½ΠΎ этот ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π½Π΅Π²Π΅Ρ€Π΅Π½, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ remove_if Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΡƒΠ΅Ρ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ ΠΎΠ½ ΡƒΠ΄Π°Π»ΠΈΡ‚ всС элСмСнты, ΡƒΠ΄ΠΎΠ²Π»Π΅Ρ‚Π²ΠΎΡ€ΡΡŽΡ‰ΠΈΠ΅ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌΡƒ ΠΊΡ€ΠΈΡ‚Π΅Ρ€ΠΈΡŽ. Он Π½Π΅ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ΠΈΡ€ΡƒΠ΅Ρ‚ порядок, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ ΡΠΎΠ²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ΡΡ ΠΎΠ±Ρ…ΠΎΠ΄ ΠΈΠ»ΠΈ ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠ΅ элСмСнтов ΠΈΠ· ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅ΠΌΠΎΠ³ΠΎ Π΄ΠΈΠ°ΠΏΠ°Π·ΠΎΠ½Π°, Ρ‚Π°ΠΊ Ρ‡Ρ‚ΠΎ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Π½Ρ‹ΠΉ ΠΊΠΎΠ΄ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π½Π΅ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΎ ΠΈ, Π±ΠΎΠ»Π΅Π΅ Ρ‚ΠΎΠ³ΠΎ, Π½Π΅ выполняСтся.

ΠšΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½Ρ‹ΠΉ способ удалСния Ρ‚Ρ€Π΅Ρ‚ΡŒΠ΅Π³ΠΎ элСмСнта β€” Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ ΠΈΡ‚Π΅Ρ€Π°Ρ†ΠΈΠΈ для Π΅Π³ΠΎ поиска ΠΈ Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ erase.

Бсылки

[Austern99] Β§4.2.2 β€’ [Josuttis99] Β§5.8.2, Β§8.1.4 β€’ [Meyers01] Β§39 β€’ [Stroustrup00] Β§10.2.6 β€’ [Sutter02] Β§2-3

88. Π’ качСствС Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠΎΠ² ΠΈ ΠΊΠΎΠΌΠΏΠ°Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠ² Π»ΡƒΡ‡ΡˆΠ΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹, Π° Π½Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ

РСзюмС

ΠŸΡ€Π΅Π΄ΠΏΠΎΡ‡Ρ‚ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Ρ‚ΡŒ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠ°ΠΌ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹, Π° Π½Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, Π° ΠΊΠΎΠΌΠΏΠ°Ρ€Π°Ρ‚ΠΎΡ€Ρ‹ ассоциативных ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ΠΎΠ² просто Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹ΠΌΠΈ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌΠΈ. Π€ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ Π°Π΄Π°ΠΏΡ‚ΠΈΡ€ΡƒΠ΅ΠΌΡ‹ ΠΈ, Π²ΠΎΠΏΡ€Π΅ΠΊΠΈ оТиданиям, ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ Π΄Π°ΡŽΡ‚ Π±ΠΎΠ»Π΅Π΅ быстрый ΠΏΠΎ ΡΡ€Π°Π²Π½Π΅Π½ΠΈΡŽ с функциями ΠΊΠΎΠ΄.

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

Π’ΠΎ-ΠΏΠ΅Ρ€Π²Ρ‹Ρ…, Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ Π»Π΅Π³ΠΊΠΎ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Π°Π΄Π°ΠΏΡ‚ΠΈΡ€ΡƒΠ΅ΠΌΡ‹ΠΌΠΈ (ΠΈ Ρ‚Π°ΠΊΠΈΠΌΠΈ ΠΈΡ… ΠΈ слСдуСт Π΄Π΅Π»Π°Ρ‚ΡŒ β€” см. Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°Ρ†ΠΈΡŽ 89). Π”Π°ΠΆΠ΅ Ссли Ρƒ вас Π΅ΡΡ‚ΡŒ готовая функция, ΠΈΠ½ΠΎΠ³Π΄Π° для Π΅Π΅ использования трСбуСтся "ΠΎΠ±Π΅Ρ€Ρ‚ΠΊΠ°" ΠΈΠ· ptr_fun ΠΈΠ»ΠΈ mem_fun. НапримСр, такая ΠΎΠ±Π΅Ρ€Ρ‚ΠΊΠ° трСбуСтся ΠΏΡ€ΠΈ построСнии Π±ΠΎΠ»Π΅Π΅ слоТных Π²Ρ‹Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ с использованиСм связыватСлСй (см. Ρ‚Π°ΠΊΠΆΠ΅ Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°Ρ†ΠΈΡŽ 84):

inline bool isHeavy(const Thing&) { /* ... */ }

find_if(v.begin(), v.end(), not1(IsHeavy)); // Ошибка

ΠžΠ±ΠΎΠΉΡ‚ΠΈ эту ΠΎΡˆΠΈΠ±ΠΊΡƒ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡƒΡ‚Π΅ΠΌ примСнСния ptr_fun (ΠΈΠ»ΠΈ, Π² случаС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ-Ρ‡Π»Π΅Π½Π°, mem_fun ΠΈΠ»ΠΈ mem_fun_ref), Ρ‡Ρ‚ΠΎ, ΠΊ соТалСнию, Π½Π΅ Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ Π² Π΄Π°Π½Π½ΠΎΠΌ ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠΌ случаС:

inline bool IsHeavy(const Thing&) { /* ... */ }

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

 not1(ptr_fun(IsHeavy))); // ГСроичСская ΠΏΠΎΠΏΡ‹Ρ‚ΠΊΠ°...

Π‘Π΅Π΄Π° Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ этот способ Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ, Π΄Π°ΠΆΠ΅ Ссли Π²Ρ‹ явно ΡƒΠΊΠ°ΠΆΠ΅Ρ‚Π΅ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹ шаблона ptr_fun. ΠšΠΎΡ€ΠΎΡ‚ΠΊΠΎ говоря, ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ° Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ ptr_fun Ρ‚ΠΎΡ‡Π½ΠΎ Π²Ρ‹Π²ΠΎΠ΄ΠΈΡ‚ Ρ‚ΠΈΠΏΡ‹ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚ΠΎΠ² ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΡ‹ΠΉ Ρ‚ΠΈΠΏ (Π² частности, Ρ‚ΠΈΠΏ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π° Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹Π²Π΅Π΄Π΅Π½ ΠΊΠ°ΠΊ const Thing&) ΠΈ создаСт Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½ΠΈΠΉ ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ, Π² свою ΠΎΡ‡Π΅Ρ€Π΅Π΄ΡŒ, пытаСтся Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π΄Ρ€ΡƒΠ³ΠΎΠΉ &, Π° ссылка Π½Π° ссылку Π² настоящСС врСмя Π² C++ Π½Π΅ Ρ€Π°Π·Ρ€Π΅ΡˆΠ΅Π½Π°. Π˜ΠΌΠ΅ΡŽΡ‚ΡΡ способы исправлСний языка ΠΈ/ΠΈΠ»ΠΈ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° для Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ Π΄Π°Π½Π½ΠΎΠΉ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, позволяя ссылкС Π½Π° ссылку ΡΠ²Π΅Ρ€Π½ΡƒΡ‚ΡŒΡΡ Π² ΠΎΠ±Ρ‹Ρ‡Π½ΡƒΡŽ ссылку; см. Ρ‚Π°ΠΊΠΆΠ΅ Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°Ρ†ΠΈΡŽ 89), Π½ΠΎ Π½Π° сСгодняшний дСнь ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ° остаСтся Π½Π΅Ρ€Π΅ΡˆΠ΅Π½Π½ΠΎΠΉ.

ΠŸΡ€ΠΈΠ±Π΅Π³Π°Ρ‚ΡŒ ΠΊΠΎ всСм этим ухищрСниям ΡΠΎΠ²Π΅Ρ€ΡˆΠ΅Π½Π½ΠΎ излишнС, Ссли Ρƒ вас имССтся ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎ написанный Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ (см. Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°Ρ†ΠΈΡŽ 89), ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π±Π΅Π· ΠΊΠ°ΠΊΠΎΠ³ΠΎ-Π»ΠΈΠ±ΠΎ ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎΠ³ΠΎ синтаксиса:

struct IsHeavy : unary_function<Thing, bool> {

 bool operator()(const Thing&) const { /* ... */ }

};


find_if(v.begin(), v.end(), not1(IsHeavy())) ; // OK

Π•Ρ‰Π΅ Π±ΠΎΠ»Π΅Π΅ Π²Π°ΠΆΠ½ΠΎ Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ для опрСдСлСния сравнСния Π² ассоциативных ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π°Ρ… Π²Π°ΠΌ Π½ΡƒΠΆΠ΅Π½ ΠΈΠΌΠ΅Π½Π½ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚, Π° Π½Π΅ функция. Π­Ρ‚ΠΎ связано с Ρ‚Π΅ΠΌ, Ρ‡Ρ‚ΠΎ нСльзя ΠΈΠ½ΡΡ‚Π°Π½Ρ†ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ шаблон с Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ Π² качСствС ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°:

bool CompareThings(const Thing&, const Thing&);

set<Thing, CompareThings> s; // Ошибка

ВмСсто этого слСдуСт Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ:

struct CompareThings

 : public binary_function<Thing,Thing,bool> {

 bool operator()( const Thing&, const Thing& ) const;

};


set<Thing, CompareThings> s; //OK

НаконСц, имССтся Π΅Ρ‰Π΅ ΠΎΠ΄Π½ΠΎ прСимущСство Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹Ρ… ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² β€” ΡΡ„Ρ„Π΅ΠΊΡ‚ΠΈΠ²Π½ΠΎΡΡ‚ΡŒ. Рассмотрим ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ Π·Π½Π°ΠΊΠΎΠΌΡ‹ΠΉ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌ:

template<typename Iter, typename Compare>

Iter find_if(Iter first, Iter last, Compare comp);

Если ΠΌΡ‹ ΠΏΠ΅Ρ€Π΅Π΄Π°Π΄ΠΈΠΌ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΡƒ Π² качСствС ΠΊΠΎΠΌΠΏΠ°Ρ€Π°Ρ‚ΠΎΡ€Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ

inline bool Function(const Thing&) { /* ... */ }

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

Ρ‚ΠΎ Π½Π° самом Π΄Π΅Π»Π΅ Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π° ссылка Π½Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ. ΠšΠΎΠΌΠΏΠΈΠ»ΡΡ‚ΠΎΡ€Ρ‹ Ρ€Π΅Π΄ΠΊΠΎ Π²ΡΡ‚Ρ€Π°ΠΈΠ²Π°ΡŽΡ‚ Π²Ρ‹Π·ΠΎΠ²Ρ‹ Ρ‚Π°ΠΊΠΈΡ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ (Π·Π° ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ΠΌ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ свСТих компиляторов, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π² состоянии провСсти Π°Π½Π°Π»ΠΈΠ· всСй ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Π² Ρ†Π΅Π»ΠΎΠΌ), Π΄Π°ΠΆΠ΅ Ссли ΠΎΠ½ΠΈ ΠΎΠ±ΡŠΡΠ²Π»Π΅Π½Ρ‹ ΠΊΠ°ΠΊ Ρ‚Π°ΠΊΠΎΠ²Ρ‹Π΅ ΠΈ Π²ΠΈΠ΄ΠΈΠΌΡ‹ Π² ΠΌΠΎΠΌΠ΅Π½Ρ‚ компиляции Π²Ρ‹Π·ΠΎΠ²Π° find_if. ΠšΡ€ΠΎΠΌΠ΅ Ρ‚ΠΎΠ³ΠΎ, ΠΊΠ°ΠΊ ΡƒΠΆΠ΅ ΡƒΠΏΠΎΠΌΠΈΠ½Π°Π»ΠΎΡΡŒ, Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π½Π΅ Π°Π΄Π°ΠΏΡ‚ΠΈΡ€ΡƒΠ΅ΠΌΡ‹.

Π”Π°Π²Π°ΠΉΡ‚Π΅ ΠΏΠ΅Ρ€Π΅Π΄Π°Π΄ΠΈΠΌ Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΡƒ find_if Π² качСствС ΠΊΠΎΠΌΠΏΠ°Ρ€Π°Ρ‚ΠΎΡ€Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹ΠΉ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚:

struct FunctionObject : unary_function<Thing, bool> {

 bool operator()(const Thing&) const { /* ... */ }

};

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

Если ΠΌΡ‹ ΠΏΠ΅Ρ€Π΅Π΄Π°Π΅ΠΌ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΈΠΌΠ΅Π΅Ρ‚ (явно ΠΈΠ»ΠΈ нСявно) встраиваСмый ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ operator(), Ρ‚ΠΎ Ρ‚Π°ΠΊΠΈΠ΅ Π²Ρ‹Π·ΠΎΠ²Ρ‹ компиляторы Π‘++ способны Π΄Π΅Π»Π°Ρ‚ΡŒ встраиваСмыми ΡƒΠΆΠ΅ ΠΎΡ‡Π΅Π½ΡŒ Π΄Π°Π²Π½ΠΎ.

ΠŸΡ€ΠΈΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅. Π­Ρ‚Π° ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΈΠΊΠ° Π½Π΅ являСтся ΠΏΡ€Π΅ΠΆΠ΄Π΅Π²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΠ΅ΠΉ (см. Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°Ρ†ΠΈΡŽ 8); Π΅Π΅ слСдуСт Ρ€Π°ΡΡΠΌΠ°Ρ‚Ρ€ΠΈΠ²Π°Ρ‚ΡŒ ΠΊΠ°ΠΊ прСпятствиС ΠΏΡ€Π΅ΠΆΠ΄Π΅Π²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ пСссимизации (см. Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°Ρ†ΠΈΡŽ 9). Если Ρƒ вас имССтся готовая функция β€” ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°ΠΉΡ‚Π΅ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ Π½Π° Π½Π΅Π΅ (ΠΊΡ€ΠΎΠΌΠ΅ Ρ‚Π΅Ρ… ситуаций, ΠΊΠΎΠ³Π΄Π° Π²Ρ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ ΠΎΠ±Π΅Ρ€Π½ΡƒΡ‚ΡŒ Π΅Π΅ Π² ptr_fun ΠΈΠ»ΠΈ mem_fun). Но Ссли Π²Ρ‹ ΠΏΠΈΡˆΠ΅Ρ‚Π΅ Π½ΠΎΠ²Ρ‹ΠΉ ΠΊΠΎΠ΄ для использования Π² качСствС Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π° Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΠ°, Ρ‚ΠΎ Π»ΡƒΡ‡ΡˆΠ΅ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Π΅Π³ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹ΠΌ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠΌ.

Бсылки

[Austern99] Β§4, Β§8, Β§15 β€’ [Josuttis99] Β§5.9 β€’ [Meyers01] Β§46 β€’ [Musser01] Β§8 β€’ [Sutter04] Β§25

89. ΠšΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎ ΠΏΠΈΡˆΠΈΡ‚Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹

РСзюмС

Π Π°Π·Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°ΠΉΡ‚Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ Ρ‚Π°ΠΊ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΡ… ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΠ»ΠΎΡΡŒ ΠΊΠ°ΠΊ ΠΌΠΎΠΆΠ½ΠΎ эффСктивнСС. Π’Π°ΠΌ, Π³Π΄Π΅ это Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, Π΄Π΅Π»Π°ΠΉΡ‚Π΅ ΠΈΡ… максимально Π°Π΄Π°ΠΏΡ‚ΠΈΡ€ΡƒΠ΅ΠΌΡ‹ΠΌΠΈ ΠΏΡƒΡ‚Π΅ΠΌ наслСдования ΠΎΡ‚ unary_function ΠΈΠ»ΠΈ binary_function.

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

Π€ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ ΠΌΠΎΠ΄Π΅Π»ΠΈΡ€ΡƒΡŽΡ‚ ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΠΈ Π½Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ. Подобно указатСлям Π½Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, ΠΎΠ½ΠΈ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ ΠΏΠ΅Ρ€Π΅Π΄Π°ΡŽΡ‚ΡΡ Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΏΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ. ВсС стандартныС Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΡ‹ ΠΏΠ΅Ρ€Π΅Π΄Π°ΡŽΡ‚ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ ΠΏΠΎ Π·Π½Π°Ρ‡Π΅Π½ΠΈΡŽ, ΠΈ Ρ‚ΠΎ ΠΆΠ΅ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π΄Π΅Π»Π°Ρ‚ΡŒ ΠΈ ваши Π°Π»Π³ΠΎΡ€ΠΈΡ‚ΠΌΡ‹, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€:

template<class InputIter, class Func>

Function for_each(InputIter first, InputIter last, Function f);

Π‘Π»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ, Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π»Π΅Π³ΠΊΠΎ ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒΡΡ ΠΈ Π±Ρ‹Ρ‚ΡŒ ΠΌΠΎΠ½ΠΎΠΌΠΎΡ€Ρ„Π½Ρ‹ΠΌΠΈ (для Π·Π°Ρ‰ΠΈΡ‚Ρ‹ ΠΎΡ‚ срСзки), Ρ‚Π°ΠΊ Ρ‡Ρ‚ΠΎ ΠΈΠ·Π±Π΅Π³Π°ΠΉΡ‚Π΅ Π²ΠΈΡ€Ρ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹Ρ… Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ (см. Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°Ρ†ΠΈΡŽ 54). ΠšΠΎΠ½Π΅Ρ‡Π½ΠΎ, Ρƒ вас ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ большиС ΠΈ/ΠΈΠ»ΠΈ ΠΏΠΎΠ»ΠΈΠΌΠΎΡ€Ρ„Π½Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ β€” ΠΈΡ… Ρ‚ΠΎΠΆΠ΅ Π²ΠΏΠΎΠ»Π½Π΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ; просто скройтС ΠΈΡ… Ρ€Π°Π·ΠΌΠ΅Ρ€ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΈΠ΄ΠΈΠΎΠΌΡ‹ Pimpl (указатСля Π½Π° Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ; см. Ρ€Π΅ΠΊΠΎΠΌΠ΅Π½Π΄Π°Ρ†ΠΈΡŽ 43). Π­Ρ‚Π° ΠΈΠ΄ΠΈΠΎΠΌΠ° позволяСт, ΠΊΠ°ΠΊ ΠΈ трСбуСтся, ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ внСшний ΠΌΠΎΠ½ΠΎΠΌΠΎΡ€Ρ„Π½Ρ‹ΠΉ класс ΠΌΠ°Π»ΠΎΠ³ΠΎ Ρ€Π°Π·ΠΌΠ΅Ρ€Π°, ΠΎΠ±Π΅ΡΠΏΠ΅Ρ‡ΠΈΠ²Π°ΡŽΡ‰ΠΈΠΉ доступ ΠΊ Π±ΠΎΠ³Π°Ρ‚ΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ. Π’Π½Π΅ΡˆΠ½ΠΈΠΉ класс Π΄ΠΎΠ»ΠΆΠ΅Π½ ΡƒΠ΄ΠΎΠ²Π»Π΅Ρ‚Π²ΠΎΡ€ΡΡ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ условиям.

β€’ Π‘Ρ‹Ρ‚ΡŒ Π°Π΄Π°ΠΏΡ‚ΠΈΡ€ΡƒΠ΅ΠΌΡ‹ΠΌ. НаслСдуйтС Π΅Π³ΠΎ ΠΎΡ‚ unary_function ΠΈΠ»ΠΈ binary_function.

β€’ Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΈΠ΄ΠΈΠΎΠΌΡƒ Pimpl. Π’Π°ΠΊΠΎΠΉ класс содСрТит ΡƒΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, shared_ptr) Π½Π° (Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, большого Ρ€Π°Π·ΠΌΠ΅Ρ€Π°) Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎΠΉ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ.

β€’ Π˜ΠΌΠ΅Ρ‚ΡŒ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€(Ρ‹) Π²Ρ‹Π·ΠΎΠ²Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ. Π­Ρ‚ΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€Ρ‹ ΠΏΠ΅Ρ€Π΅Π΄Π°ΡŽΡ‚ Π²Ρ‹Π·ΠΎΠ²Ρ‹ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρƒ-Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ.