【发布时间】:2020-11-01 02:51:26
【问题描述】:
我会以我对合理的替代方案持开放态度这一事实作为这个问题的开头,这是我们目前陷入困境的地方。
我们希望在我们的游戏引擎中有一个 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++,并且有据可查,可以按照您想要的方式工作。
-
OP 没有创建这些:docs.microsoft.com/en-us/cpp/cpp/…
标签: c++