簡體   English   中英

C ++宏中的函數式編程樣式:是否在任何地方都有記錄?

[英]Functional-Programming Style in C++ Macros: Is this documented anywhere?

閱讀一些C ++代碼后,我大致看到了所謂的函數宏的“函數式”用法(大致來說,這是一個風格化的例子):

#define TOP_LEVEL(ARG1)     \
ARG1("foo1","bar1")     \
ARG1("foo2","bar2")

#define NEXT_LEVEL(ARG2A, ARG2B)    \
cout << ARG2A << " and " << ARG2B;

TOP_LEVEL(NEXT_LEVEL)

我是該語言的新手,起初我無法弄清楚,但是后來我僅通過預處理器( g++ -E )來運行它,瞧瞧它解析為:

cout << "foo1" << " and " << "bar1"; cout << "foo2" << " and " << "bar2";

你看到那里做了什么嗎? 像指向宏TOP_LEVEL 的函數指針一樣傳遞了宏NEXT_LEVEL。 看到這可能有多大用處之后,我想了解更多有關它的知識:將函數傳遞給其他函數是相當復雜的事情,並且至少應該對這種技術說些什么。

盡管進行了大量的谷歌搜索,但我找不到證據表明預處理器的這一功能甚至存在,更不用說任何即將來臨的文檔了: 這里這里這里這里只是四個Macro教程的例子,它們跳過了這些; 最后一個甚至有一個名為“高級宏技巧”的部分-當然可以滿足要求!

(請注意,這與簡單地調用帶有另一個已評估函數宏作為參數的函數宏完全不同-FOO(BAR(2))更為簡單。)

我的問題是:

  • 有此行為的實際名稱嗎?
  • 它記錄在任何地方嗎?
  • 它是常用的,還是有眾所周知的陷阱等?

這個想法被稱為“ X-宏”。 一些定義將不包括您的特定示例(X-macros通常會涉及到更多點,其中包含一個文件),但是會包含任何相關信息。 搜索時,有關此字詞的信息將歸入該字詞。

正如克里斯在評論中提到的那樣,Boost.Preprocessor使用此想法產生了很大的效果。 流行的用法是: BOOST_PP_REPEATBOOST_PP_LIST_FOR_EACH ,以及最強大的用法: BOOST_PP_ITERATE

BOOST_PP_ITERATE是“真實”的X宏; 包括單個文件的內容將擴展為依賴於之前定義的宏的內容。 我在另一個答案中展示了一個更“合適”的框架框架,但是一個例子是:

// in xyz_data.def
DEFINE_XYZ(foo, 1, "Description A")
DEFINE_XYZ(bar, 5, "Description B")
DEFINE_XYZ(baz, 7, "Description C")

然后,當我只想要第1列時,我可以執行以下操作:

#define DEFINE_XYZ(name, number, desc) some_func(name)
#include "xyz_data.def"

在我想為每個函數生成某些函數的其他地方,我可以執行以下操作:

#define DEFINE_XYZ(name, number, desc)                              \
    int BOOST_PP_CAT(get_number_for_, name)()                       \
    {                                                               \
       std::clog << "Getting number, which is: " desc << std::endl; \
                                                                    \
       return number;                                               \
    }

#include "xyz_data.def"

然后,您可以生成名稱等於數字等的枚舉。

強大之處在於,當我想添加新的xyz時,只需將其添加到一個位置,它就會神奇地顯示在需要的任何位置。 我已經在一個非常大的代碼庫中執行了類似的操作,以將一些書簽數據保留在一個中央位置,但是各種屬性在不同位置使用的方式有所不同。

請注意,通常無法解決此問題。 我在語法上有所不同 ,因此沒有其他語言功能可以將其推廣到該級別,只有宏。 宏不是邪惡的。

您所擁有的實際上是一個X宏,其中.def文件是自包含的,足以成為#define 換句話說, #include "xyz_data.def"只是TOP_LEVEL

這樣做只有一個很大的缺點,具有諷刺意味的是,這並不是使用X宏本身,而是它們對C和C ++編譯器的影響。 問題在於,即使文件內容完全相同 ,預處理器也允許我們在每次包含文件時更改文件的預處理結果。

您可能已經聽說,與現代語言相比,C和C ++的編譯速度較慢,這就是原因之一。 它沒有適當的模塊/打包系統,只是臨時包含其他文件。 而且我們剛剛了解到, 通常這是無法避免的 哎呀。 (也就是說,編譯器很聰明,例如會在您在文件周圍包含防護措施時予以注意,並避免多次處理它。但這是根據情況而定。)

就是說,使用X-Macros本身不應該對真正程序的編譯時間做出巨大貢獻。 僅僅是它們的潛在存在延伸到了真正的詞里,並在編譯器的頭腦中screws繞。

這里有一些講座: C是純函數式的

我建議您看看libppmacrofun

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM