[英]How can I macro #define a static method call in C++?
我正在嘗試編寫一種軟件,該軟件可以根據某個組件是應該在軟件中進行仿真還是在實際硬件上執行來改變行為。 但是,GCC抱怨范圍解析運算符(::)不能在宏中使用,所以我的問題是:是否可以為靜態方法調用定義宏?
我的目標是能夠使用另一個預處理程序定義,在使用所有實際組件(0),使用所有模擬組件(1)或使用真實和模擬組件的混合(2)之間進行選擇。 這是我遇到此問題的最后一種情況。 在這種情況下,我想通過將其實現為靜態方法來調用我正在“保護”的函數。 這是我的方法:
#define SIM_CONF 2
#if SIM_CONF == 0
#define IS_HW_SIMULATED(name) false
#define IS_HW_REAL(name) true
#endif
#if SIM_CONF == 1
#define IS_HW_SIMULATED(name) true
#define IS_HW_REAL(name) false
#endif
#if SIM_CONF == 2
#define IS_HW_SIMULATED(name) SimConfig::isSimulated(name)
#define IS_HW_REAL(name) SimConfig::isReal(name)
#endif
class SimConfig
{
public:
static bool isSimulated(const char* szName);
static bool isReal(const char* szName);
};
編輯:這是我在其他地方使用它的示例:
void PumpComponent::commandRevs(float revs)
{
#if IS_HW_SIMULATED("PumpComponent")
// do simulation procedure
#else
// do real hardware procedure
#endif
}
當我編譯時,GNU Make抱怨:
error: token "::" is not valid in preprocessor expressions #define IS_HW_SIMULATED(name) SimConfig::isSimulated(name)
有什么方法可以保護/封裝isSimulated()
和isReal()
函數,並且仍然能夠在預處理器指令中引用它們?
問題是您如何使用此宏。 您已將其放置為預處理器#if
參數。
處理器不理解#if
代碼和參數必須是處理器可以處理的內容,因此宏和文字。
SimConfig::isSimulated
是尚未定義的代碼。 在編譯過程中會知道,因此在預處理完成之后。
要解決這個問題的方法之一是簡單地使用if
else
void PumpComponent::commandRevs(float revs)
{
if IS_HW_SIMULATED("PumpComponent") {
// do simulation procedure
} else {
// do real hardware procedure
}
}
對於編譯器來說不是問題。 它將注意到這是恆定的,應該刪除過時的代碼。
解決它的另一種方法是放棄宏。 您可以使用模板。
或者在某些類中包含宏相關的內容,並使用宏來更改該類的功能(這樣,此宏將不會遍及您的代碼)。
不要為此使用#if
。 只需編寫普通代碼:
void PumpComponent::commandRevs(float revs)
{
if (IS_HW_SIMULATED("PumpComponent")) {
// do simulation procedure
} else {
// do real hardware procedure
}
}
當SIM_CONF
為0或1時,編譯器將刪除其中一個分支,因為分支條件是編譯時常量。 當它是2時,它將保留分支。
但是,我完全沒有理由擁有IS_HW_SIMULATED
和IS_HW_REAL
宏。 查看您發布的代碼,看來您只需要一個函數: SimConfig::isSimulated()
:
bool SimConfig::isSimulated(const char* szName)
{
#if SIM_CONF == 1
(void)szName; // supress "unused parameter" warning
return true;
#else
// Your normal implementation.
#endif
}
其余的代碼則不需要使用任何宏:
void PumpComponent::commandRevs(float revs)
{
if (SimConfig::isSimulated("PumpComponent")) {
// do simulation procedure
} else {
// do real hardware procedure
}
}
SimConfig::isReal()
似乎沒有任何作用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.