2012-05-14 25 views
0

基本上它是下面的代碼,它可以不通過編譯器(克++)使用boost :: program_options作爲一類的靜態成員

#include <boost/program_options.hpp> 
#include <iostream> 
using std::cout; 
using std::endl; 
namespace po = boost::program_options; 

class static_class { 
public: 
    static po::options_description cmd_opt; // here is the definition 
}; 

po::options_description static_class::cmd_opt("dummy"); 
// the line below cannot pass the compiler !!! 
static_class::cmd_opt.add_options() 
("help", "show usage info.") 
; 

main() { 
    cout << static_class::cmd_opt << endl; 
} 

錯誤消息:

test.cpp:16:1: error: ‘cmd_opt’ in class ‘static_class’ does not name a type 

任何想法?

P.S. 我試圖定義我需要在一個小的命令行環境來處理每個命令分開options_description。我正在使用bison和flex來解析命令行環境。一個命令的所有參數都將被髮送到這個靜態類以進行參數分析。

爲參數的定義是靜態的,我不想讓他們某種數據結構的堆疊(只是在我的腦海裏可能這是快速,乾淨)。我認爲如果這些代碼不是靜態的,那麼這些代碼就可以了,但如果他們是靜態的,會發生什麼?

回答

3

地方不允許你有全局或命名空間範圍內的獨立語句。

你可以通過使用擴展add_options表達的返回值如下聲明和初始化一個虛擬變量,得到解決此問題。

po::options_description static_class::cmd_opt("dummy"); 

auto const dummy = cmd_opt.add_options() 
    ("help", "show usage info.") 
    ; 

如果你的C++的版本不支持auto這樣,那麼你可以使用該類型的全名,po::options_description_easy_init,來代替。

+0

這看起來有點奇怪,但太棒了!我會稍後再試。 –

+0

我認爲添加靜態到虛擬變量,使其只能在本地文件中可見更好。在這個相同的虛擬變量可以用在多個cpp文件中。 –

3

.add_options()的呼叫是函數調用,而不是聲明。您正嘗試在函數之外運行代碼。試試這個:

// untested 
void PopulateOptions() { 
    static_class::cmd_opt.add_options() 
    ("help", "show usage info.") 
    ; 
} 

int main() { 
    PopulateOptions(); 
} 
+0

你是對這個錯誤的原因,但明確將在主函數調用()這正是我想避免的。 –

+0

如果這是一個重要的限制條件,將它添加到您的原始文章將會很好。 –

3

options_description來看它需要一個兩階段的初始化:調用構造函數,然後調用add_options()來填充它。您的代碼試圖做第二階段的功能範圍之外,將失敗,因爲調用add_options()必須在功能範圍內進行。

一個解決它的方法是創建初始化並填充一個options_description對象,並返回其出廠功能。該返回對象可用於初始化靜態實例static_class::cmd_opt,例如:

// in .cc 

namespace { 

po::options_description make_options_description() { 
    po::options_description opt("dummy"); 
    opt.add_options() // ... populate ... 
    return opt; 
} 

} 

po::options_description static_class::cmd_opt = make_options_description(); 

另一個選項,而不是暴露po::options_description靜態部件,露出用於填充通過引用傳遞一個po::options_description對象的功能,例如:

class static_class { 
public: 
    // requires only a forward declaration of po::options_description 
    static void add_options(po::options_description&); 
}; 

// in .cc 
void static_class::add_options(po::options_description& opt) { 
    opt.add_options() // ... populate ... 
} 

然後在main()

po::options_description opt; 
static_class::add_options(opt); 
another_static_class::add_options(opt); 
yet_another_static_class::add_options(opt); 
+0

非常感謝,直接點!對不起,只有一個答案可以接受。 –