2017-03-02 55 views
0

我有一個散佈在我的代碼中的函數。它用於開發,但我不希望它在最終系統中運行。這樣做的一個方法是使用宏:C++如何選擇性替換空函數中的函數

#if SPEAK_ENABLED 
    #define speak(m) implementation(m) 
#else 
    #define speak(m) ((void)0) 
#endif 

這個效果很好,但我不知道是否有任何其他機構(可能使用模板),我可以用它來獲得一個相似的行爲。

我試過的一件事是聲明一個函數,然後在所有主要的.cpp文件中提供一個實現。例如:

enable.h:

void speak() 
{ 
     std::cout << "Output enabled" << std::endl; 
} 

disable.h:

void speak() 
{ 
} 

silent_main.h:

#include "disable.h" 

int main(int argc, char *argv[]) 
{ 
     speak(); 
     return 0; 
} 

talking_main.h:

#include "enable.h" 

int main(int argc, char *argv[]) 
{ 
     speak(); 
     return 0; 
} 

這適用於上述簡單情況,但它不適用於我的庫,因爲它們會在鏈接時缺少函數的定義。

這基本上是我的用例。我想爲一個可執行目標禁用此功能,但爲所有其他目標啓用此功能。

這僅僅是其中使用宏是合理的情況之一嗎?

+0

您的宏示例實際上是錯誤的 - 在#if分支中,您不應該用分號終止擴展命令,在#else分支中您應該擴展爲無操作((void)0 )'而不是 – UnholySheep

+0

感謝您的信息。這就說得通了。我迅速從其他地方複製它。我將編輯修復它。 – user2445507

回答

0

對於「條件編譯」,宏仍然有用 - 至少考慮到您可以在大多數編譯器調用的參數中定義或取消定義它們的優點。

例如,這是有用的#include <cassert>assert,及其與NDEBUG宏關係。


如果SPEAK_ENABLED取決於型或無型的一些編譯時的財產,那麼你可以使用一個模板,你將如何做到這一點取決於你的用例。

:但是,如果SPEAK_ENABLED依賴於編譯器調用之前已知的某些環境屬性,則MACRO仍可能具有某種相關性。


這適用於簡單的情況下,像上面的,但它不會在我的 圖書館工作,因爲他們會抱怨缺乏 定義功能目前正在聯繫時,他們。

爲「禁用案例」提供speak()的空白定義,優秀的優化器可能會刪除該調用。

+0

我與模板的問題是依賴性問題。例如,我可以定義一個接受int作爲模板參數的函數,但是我無法從main.cpp文件中定義該int,因此它可以在我的庫中找到。我猜在這種情況下唯一的解決方案是宏。 – user2445507

+0

那麼,現在它編譯宏,但我有一個類似的問題。該宏沒有設置在依賴庫中,因此它們仍然執行完整的speak()函數,而我的main.cpp可執行文件已禁用它。我可能需要使用一些更復雜的makefile來真正讓它在所有依賴庫中工作...... – user2445507