[英]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.