2013-12-17 64 views
2

我花了一天的時間閱讀筆記,並觀看了關於boost :: fusion的視頻,我真的不知道它的某些方面。boost :: fusion的目的是什麼?

舉例來說,boost::fusion::has_key<S>函數。在boost :: fusion中有什麼目的?我們是否試圖儘可能在編譯時儘可能多地編程?所以幾乎所有boost::fusion函數都與運行時版本相同,除了現在在編譯時計算? (並且我們認爲在編譯時做更多是好事?)。

與boost :: fusion相關,我也有點困惑爲什麼元函數總是返回類型。爲什麼是這樣?

+6

我寧願在編譯時發現錯誤,而不是在運行時發現錯誤。 –

+0

是元組的STL。如果您將類映射到元組,您可以將其用於編譯時反射。 – gnzlbg

回答

2

融合是編譯時和運行時間容器和算法之間的橋樑。您可能會也可能不希望將一些處理過程轉移到編譯時,但如果您確實想要,Fusion可能會提供幫助。儘管我可能是錯的,但我認爲它沒有具體的宣言,儘可能多地進行編譯。

元函數返回類型,因爲模板元編程不是故意發明的。無意中發現C++模板可以用作編譯時編程語言。元函數是從模板參數到模板實例的映射。從C++ 03開始,有兩種模板(類和函數),因此元函數必須「返回」類或函數。類比函數更有用,因爲您可以將值等放入其靜態數據成員中。

C++ 11增加了另一種模板(用於typedefs),但這與元編程無關。更重要的是對於編譯時編程,C++ 11增加了constexpr函數。它們是爲了這個目的而設計的,它們像普通函數一樣返回值。當然,他們的輸入不是一種類型,所以他們不能以模板可以從類型映射到其他東西。所以在這個意義上,他們缺乏元編程的「元 - 」部分。它們只是對普通C++函數的編譯時評估,而不是元函數。

4

查看boost :: fusion的另一種方法是將其視爲「窮人自省」庫。 boost :: fusion的原始動機來自boost :: spirit分析器/生成器框架的方向,特別是需要支持所謂的「分析器屬性」。

想象一下,你已經有了一個CSV字符串解析:

AAAA,1.1

的類型,這個字符串解析成,可謂是 「字符串和雙元組」 。我們可以用「普通」C++定義這樣的元組,或者與舊式結構(struct { string a; double b; }或更新的tuple<string, double>)一起定義。我們唯一想念的是某種適配器,它將允許將任意組合的元組(或其他類型)傳遞給統一的分析器接口,並期望它能夠理解它,而不會傳遞任何帶外信息(如字符串解析scanf使用的模板)。

這就是boost :: fusion的作用。構建「融合序列」的最直接方式是適應正常結構:

struct a { 
    string s; 
    double d; 
}; 
BOOST_FUSION_ADAPT_STRUCT(a, (string, s)(double, d)) 

的「ADAPT_STRUCT」宏增加了對解析器框架必要的信息(在本例),以便能夠「迭代」過struct a的成員調出以下問題:

  1. 我剛剛解析了一個字符串。我可以將它分配給struct a的第一個成員嗎?

  2. 我剛剛解析了一個double。我可以將它分配給struct a的第二位成員嗎?

  3. struct a中還有其他成員還是應該停止解析?

顯然,這個基本的例子還可以進一步擴展(和boost ::融合提供的能力),以解決更復雜的情況:

  1. 變種 - 比方說解析器可以遇到任何刺痛或雙倍,並且希望將其分配給struct a的正確成員。 BOOST_FUSION_ADAPT_ASSOC_STRUCT來拯救(現在我們的解析器可以提問像「哪個成員struct a是double類型?」)。

  2. 轉換 - 我們的解析器可以被設計爲接受某些類型的參數,但其餘的程序已經發生了很大的變化。然而,融合元功能可以方便地用於使新類型適應舊的現實(反之亦然)。

boost :: fusion函數的其餘部分自然就是從上面的基礎開始的。如果需要將「鬆散IO數據」轉換爲強類型/結構化數據(如果需要考慮效率),C++程序需要進行轉換(在任一方向),融合才真正發揮作用。它是spirit :: qi和spirit :: karma成爲如此高效(可能是最快)的I/O框架的支持因素。

相關問題