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
;
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
@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. –
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