c++ - C ++如何有条件地调用全局函数,无论是否在静态方法中?
问题描述
我将以我对合理的替代方案持开放态度这一事实作为这个问题的开头,这就是我们目前陷入困境的地方。
我们希望在我们的游戏引擎中有一个 Assert() 宏,如果从 GameObject 方法中调用,它能够自动记录有关基本 GameObjects 的元数据。询问 SO 的动机是,我们目前受困于两个断言变体:Assert() 和 AssertInStatic(),但更喜欢只有一个。
代码问题(注意:不是确切的代码,但概述了问题):
// macro
#define Assert(expr, msg) \
if (!(expr)) DoAssert(msg, __FILE__, __LINE__)
#define AssertInStatic(expr, msg) \
if (!(expr)) ::DoAssert(msg, __FILE__, __LINE__)
// global function
bool DoAssert(msg, file, line);
class GameObject {
protected:
// game object assert method
bool DoAssert(msg, file, line); // logs extra object metadata
};
// any global function or non-GameObject method
void foo()
{
Assert(condition, "msg"); // calls global assert function
}
// regular GameObject method
void GameObject::foo()
{
Assert(condition, "msg"); // calls GameObject assert method
}
// STATIC GameObject method
/*static*/ void GameObject::static_foo()
{
//Assert(condition, "msg"); // <ERROR: class assert method uncallable, hides global function>
AssertInStatic(condition, "msg"); // works, calls global assert, but would rather not have this special case
}
我们找到的最接近的解决方案在 MSVC 上是这样的(但我们也需要该解决方案可以在 clang 和 gcc 之间移植):
// msvc:
__if_exists(this) {
DoAssert(...);
}
__if_not_exists(this) {
::DoAssert(...);
}
解决方案
您可以考虑使用可变参数宏来重载带有可选参数的宏名称。因此参数的数量将区分全局和对象断言。它可能是一个虚拟参数或特定于对象的东西。
请参阅C++ 宏的可选参数。
推荐阅读
- flutter - 容器构造完成后添加一个子容器
- django - request.data 每个变量的变化
- ionic-framework - 从 InAppBrowser IONIC 5 获取 JSON 数据
- javascript - react-select 默认值设置但未突出显示
- jquery - 仅保留文本字符串中的数字并用于计算总数
- javascript - 使用 eslint 强制特定的命名导出?
- react-native - React 原生 Agora SDK 中的交互式直播
- r - 应用于多个数据框中的每一列
- java - Android 测试 - 带有 queryIntentActivities 的函数返回空列表
- vue.js - 如何在 Tawk.to 插件中更改 Vue.use() 中的选项值更改 tawkSrc: 字符串值,尝试在 nuxt FOR TAWK.TO MULTILANGUAGE / 更改小部件