2011-08-19 57 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

哦,現在我明白了。你必須尋找「通知者」,不通知。通知函數是通過一個const引用值,所以不能改變它?如果選項「不好」,除了拋出異常外,我不會看到太多的東西。 – olooney

+0

@olooney:意圖是你採取任何預期的行動將與該選項。例如,如果您有更改搜索路徑的選項,您的通知程序功能將修改搜索路徑。正如我在回答中所指出的那樣,您可以在選項解析代碼中執行相同的邏輯,方法是分別檢查每個選項,然後執行一些操作,但這會導致很長的程序性blob,難以讀取或修改。 –

+2

當然,但是沒有能力改變variable_map,將不透明的句柄傳遞給環境對象,或者綁定到functor(使用boost :: function),你真的只限於異常和* global *副作用。這對於更改工作目錄或設置全局「詳細」標誌仍然很有用,但它不足以將大部分選項解析移動到通知程序。也許我應該在做出判斷之前嘗試一下,我只是在這裏推理。 – 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 
    ; 
相關問題