2011-08-19 5 views
26

이 질문은 C++ Boost program_options 라이브러리에 관한 것입니다.boost :: program_options :: notify()는 무엇입니까?

모든 튜토리얼은 내가 완료 한 변수 맵에 notify()을 호출해야한다는 것을 분명히하지만, 실제로 이것이 나를 위해 무엇을하는지 잘 모르겠습니다. 그것을 언급하는 것은 어떤 영향을 미칠 것 같지 않았고, 문서는 많은 세부 사항에 가지 않았다 :

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

다른 소스는 "사용자 정의"기능을 실행하는 것이 좋습니다. 그렇다면, 어떻게 그 기능들이 등록되고 그것들은 무엇을 하는가? 그들은 예외를 던질 수 있습니까?

답변

20

notify()member function of value_semantic입니다. 옵션의 최종 값이 결정되면 해당 옵션으로 수행해야하는 모든 작업을 자동으로 수행하고 자체 기능으로 캡슐화 할 수 있도록 제공되는 후크입니다. 이렇게하면 코드가 각 옵션에서 작동하는 하나의 긴 함수를 갖지 못합니다. 가능한 옵션이 커짐에 따라, 그런 종류의 절차 코드는 다루기 힘들 수 있습니다.

당신은 an example of setting a notify function in the Boost manual 볼 수 있습니다 :

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

이 선언 첫 번째 옵션의 디폴트 값을 지정하면 두 번째 옵션은 여러 번 모든 인스턴스를 표시 할 수 있습니다 통합되어야하고 있다는 것을, 10 구문 분석이 끝나면 라이브러리는 함수 & your_function을 호출하고 "email"옵션의 값인 을 인수로 전달합니다.

+0

아, 내가 지금 그것을 볼 신고자없이, 당신의 코드를 다음과 같이 보일 수 있습니다. 알리지 않고 "알리미"를 찾아야합니다. notify 함수가 value에 대한 const 참조를 지나치므로 변경할 수 없습니다. 옵션이 "나쁘다"면 예외를 던지는 것 외에는 할 수있는 일이 많지 않습니다. – olooney

+0

@olooney : 의도는 의도 한 행동을 그 옵션으로 취하는 것입니다. 예를 들어 검색 경로를 변경하는 옵션이있는 경우 알림 기능이 검색 경로를 수정합니다. 내 대답에, 당신은 귀하의 옵션을 구문 분석 코드 에서이 옵션을 개별적으로 확인하고 몇 가지 조치를 취 함으로써이 같은 논리를 할 수 있지만, 읽기 또는 수정하기 어려운 긴 절차 BLOB가 발생할 수 있습니다. –

+2

물론, variable_map을 변경하거나, 환경 객체에 불투명 한 핸들을 전달하거나, functor에 바인딩하는 기능이 없으면 (예 : boost :: function을 사용하여), 예외 및 전역 * 부작용에 실제로 국한됩니다. 이는 여전히 작업 디렉토리를 변경하거나 전역 "자세한 정보 표시"플래그를 설정하는 데 유용하지만 대량의 옵션 구문 분석을 알리미로 옮기는 것은 일반적이지 않습니다. 내가 심판을하기 전에 그것을 시도해야 할지도 모르겠다. 나는 여기서 이론을 세우고있다. – olooney

4

나는

그것은 옵션이 어떤 객체의 메소드에 인수 (들)을 전달하여 처리하기가 매우 일반적입니다 ... 당신이 "펑"를 언급 할 때 바른 길에 생각합니다. notifier()가 인수로 받아 들일 수있는 메소드로 메소드를 래핑 할 수있는 경우,이를 직접 알 고리즘을 사용하여 수행 할 수 있습니다. 그리고 당신은 할 수 있습니다. (boost :: function에 그렇게하는 방법이 있다면, 충분히 익숙하지 않아서 (지금은 공부하기에 너무 게으르다.) - 다음은 STDLIB의 헤더에서 루틴을 사용한다.)

예 :

옵션 중 하나는 기본값이 아닌 구성 파일의 경로를 알려주는 문자열 인수를 취하는 --config-file입니다. ConfigParser라는 클래스가 있습니다. 신고자와

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 
    ; 
관련 문제