myślę, że jesteś na dobrej drodze, kiedy wspomina „funktor” ...
To dość typowe dla opcją być przetwarzane przez przepuszczenie jej argumentu (ów) do metody jakiegoś obiektu. Można to zrobić bardziej bezpośrednio z powiadamiającymi, jeśli można zawrzeć metodę w coś, co notifier() zaakceptuje jako argument. I możesz. (Jeśli funkcja boost :: ma taki sposób, nie jestem dostatecznie zaznajomiony z tym (i jestem zbyt leniwy, aby przejść do badania na nim teraz) - poniższe używa procedur w nagłówku funkcjonalnym od STDLIB.)
Przykład:
Jedną z opcji jest --config-file, pobierający ciąg znaków, który przekazuje ścieżkę do innego niż domyślny pliku konfiguracyjnego. Masz klasę o nazwie ConfigParser. Bez zgłaszających, kod może wyglądać mniej więcej tak:
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);
ze zgłaszającym:
#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
;
Och, teraz to widzę. Musisz szukać "powiadamiającego", a nie powiadamiać. Funkcja powiadamiania jest za odniesieniem do wartości stałej, więc nie może jej zmutować? Nie widzę wiele, co możesz zrobić z tym innym niż wyrzucić wyjątek, jeśli opcja jest "zła". – olooney
@olooney: Chodzi o to, abyś wziął wszystko, co zamierzała akcja z tą opcją. Na przykład, jeśli masz opcję, która zmienia ścieżkę wyszukiwania, funkcja powiadamiającego zmodyfikuje ścieżkę wyszukiwania. Jak zauważam w mojej odpowiedzi, można wykonać tę samą logikę w kodzie analizowania opcji, sprawdzając każdą opcję indywidualnie, a następnie podejmując pewne działania, ale może to spowodować długi obszar proceduralny, który jest trudny do odczytania lub zmodyfikowania. –
Oczywiście, ale bez możliwości mutacji zmiennej_mapa, przekazania nieprzezroczystego uchwytu do obiektu środowiskowego lub powiązania z funktorem (używając funkcji boost :: function, powiedz), jesteś naprawdę ograniczony do wyjątków i * globalnych * efektów ubocznych. Nadal jest to przydatne przy zmianie katalogu roboczego lub ustawianiu globalnej flagi "pełnej", ale nie jest to wystarczająco ogólne, aby przenieść większość opcji analizowania do powiadamiających. Może powinienem spróbować, zanim jednak osądzę, po prostu teoretyzuję tutaj. – olooney