C ++如何用空实现有选择地替换函数
Posted
技术标签:
【中文标题】C ++如何用空实现有选择地替换函数【英文标题】:C++ How to selectively replace function with empty implementation 【发布时间】:2017-03-02 19:52:12 【问题描述】:我的代码中散布着一个函数。它用于开发,但我不希望它在最终系统中运行。一种方法是使用宏:
#if SPEAK_ENABLED
#define speak(m) implementation(m)
#else
#define speak(m) ((void)0)
#endif
这很好用,但我想知道是否有任何其他机制(可能使用模板)可以用来获得类似的行为。
我尝试过的一件事是声明一个函数,然后在我的所有主要 .cpp 文件中提供一个实现。例如:
启用.h:
void speak()
std::cout << "Output enabled" << std::endl;
禁用.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;
这适用于上述简单情况,但不适用于我的库,因为它们会在链接时抱怨缺少函数的定义。
这基本上是我的用例。我想为一个可执行目标禁用此功能,但为所有其他目标启用它。
这只是可以使用宏的实例之一吗?
【问题讨论】:
您的宏示例实际上是错误的 - 在#if
分支中,您不应使用分号终止扩展命令,而在 #else
分支中,您应该扩展为无操作 ((void)0)
而是
感谢您的信息。这就说得通了。我很快从别处复制了它。我会编辑修复它。
【参考方案1】:
宏对于“条件编译”仍然有用1 - 至少考虑到您可以在大多数编译器调用的参数中定义或取消定义它们的优势。
例如,这在 #include <cassert>
的 assert
及其与 NDEBUG
宏的关系中很有用。
如果SPEAK_ENABLED
依赖于某个类型或非类型的某个编译时属性,那么您可以使用模板,具体操作方式取决于您的用例。
1:但是,如果SPEAK_ENABLED
依赖于编译器调用之前已知的某些环境属性,那么宏可能仍然具有一定的相关性。
这适用于上述简单情况,但不适用于我的 图书馆,因为他们会抱怨缺乏定义 链接时的函数。
为“禁用情况”提供speak()
的空定义,好的优化器可能会删除调用。
【讨论】:
我的模板问题是依赖问题。例如,我可以定义一个接受 int 作为模板参数的函数,但是我无法从我的 main.cpp 文件中定义该 int 以便在我的库中获取它。我想在这种情况下唯一的解决方案是宏。 好吧,现在它可以用宏编译,但我有一个类似的问题。宏未在依赖库中设置,因此它们仍然执行完整的 speak() 功能,而我的 main.cpp 可执行文件已禁用它。我可能需要使用一些更复杂的 makefile 东西才能真正让它在我所有的依赖库中工作......以上是关于C ++如何用空实现有选择地替换函数的主要内容,如果未能解决你的问题,请参考以下文章