2011-08-19 15 views
26

Bu soru C++ Boost program_options kitaplığı hakkındadır.Ne için boost :: program_options :: notify() nedir?

Tamamlanmış değişken haritamda notify() numaralı telefonu aramam için tüm öğreticiler çok açık, ancak bunun benim için ne yaptığından emin değilim. bunu yorumlarında herhangi bir etkiye sahip değildi ve dokümantasyon fazla detaya vermedi:

http://www.boost.org/doc/libs/1_47_0/doc/html/boost/program_options/notify.html

Diğer kaynaklar da "kullanıcı tanımlı" fonksiyonlarını çalıştırır düşündürmektedir. Eğer öyleyse, bu işlevler nasıl kaydedilir ve ne yapar? İstisnalar atabilir mi?

cevap

20

notify()member function of value_semantic'dur. Bir seçeneğin nihai değeri belirlendiğinde, bu seçenekle yapılması gereken herhangi bir eylemin otomatik olarak yapılabilmesi ve kendi işlevinde kapsüllenebilmesi için sağlanan bir kancadır. Bu, kodun her bir seçenek üzerinde etkili olan uzun bir işleve sahip olmasını engeller. Olası seçenekler büyüdükçe, bu tür bir prosedür kodu kullanışsız olabilir.

Sen an example of setting a notify function in the Boost manual görebilirsiniz:

options_description desc; 
desc.add_options() 
    ("compression", value<int>()->default_value(10), "compression level") 
    ("email", value< vector<string> >() 
     ->composing()->notifier(&your_function), "email") 
    ; 

Bu bildirimleri ilk seçeneğin varsayılan değeri belirtmek İkinci seçenek birkaç kez ve tüm örneklerini görünebilir birleştirilmiş olmalı ve o, 10 ayrıştırma bittikten sonra, kütüphane çağrı fonksiyonunu & fonksiyonunuza girerek, "e-posta" seçeneğinin değerini argüman olarak geçirecektir.

+0

Oh, şimdi görmek bildirim yapacaklar olmadan, kod aşağıdaki gibi görünebilir. "Notifier" ı aramak zorundasınız, bildirimde bulunmayın. Bildirim işlevi, değer için bir const referansını geçmiş, bu yüzden değiştiremez mi? Eğer seçenek "kötü" ise bir istisna atmak dışında onunla yapabileceğiniz çok şey görmüyorum. – olooney

+0

@olooney: Amaç niyet edilen eylemin bu seçenekle ne olursa olsun onu almanızdır. Örneğin, arama yolunu değiştiren bir seçeneğiniz varsa, bildirim işleviniz arama yolunu değiştirir. Cevabımda not ettiğim gibi, her bir seçeneği tek tek kontrol ederek ve daha sonra biraz harekete geçerek, seçenek ayrıştırma kodunuzda aynı mantığı yapabilirsiniz, ancak bu, okunması veya değiştirilmesi zor uzun bir yordamsal blob ile sonuçlanabilir. –

+2

Elbette, değişken_map'i değiştirme özelliği olmadan, bir opak tanıtıcıyı bir ortam nesnesine geçirin veya functor'a bağlanın (boost :: function, say), gerçekten istisnalar ve * global * yan etkiler ile sınırlısınız. Bu, çalışma dizinini değiştirmek veya global bir "ayrıntılı" bayrağı ayarlamak için hala yararlıdır, ancak seçenek ayrıştırmanın toplu birimini bildiricilere taşımak için yeterli değildir. Belki bir yargılama yapmadan önce denemeliyim, sadece burada kuram yapıyorum. – olooney

4

Ben

Bu bir seçenek bazı nesnenin yöntemine onun argüman (lar) geçerek işlenecek için oldukça yaygındır ... siz "functor" söz ederken doğru yolda olduğunu düşünüyorum. Bu yöntemi, notifier() 'ın bir argüman olarak kabul edeceği bir şeye sarmanız halinde, bildiricilerle daha doğrudan yapılabilir. Ve yapabilirsin. (Eğer boost :: fonksiyonunun bir yolu var ise, ben yeterince tanıdık değilim (ve şimdi üzerinde çalışmaya başlamak için çok tembelim) - Aşağıdakiler STDLIB'den gelen fonksiyonalerdeki rutinleri kullanır.)

Örnek:

Seçeneklerden bir tanesi, varsayılan olmayan bir yapılandırma dosyasının yolunu söyleyen bir dize argümanı alan --config dosyasıdır. ConfigParser adlı bir sınıfınız var. bildirim yapacaklar ile

ConfigParser *cp = new ConfigParser(); 
std::string cp_path; 
desc.add_options() 
    ("config-file", value<std::string>(&cp_path)->default_value("~/.myconfig"), "Config File") 
    // ... the rest of your options 
    ; 

cp->setPath(cp_path); 

:

#include <functional> 

ConfigParser *cp = new ConfigParser(); 
desc.add_options() 
    ("config-file", value<std::string>()->default_value("~/.myconfig")->notifier(std::bind1st(std::mem_fun(&ConfigParser::setPath), cp)), "Config File") 
    // ... the rest of your options 
    ; 
İlgili konular