【问题标题】:C++ How to conditionally call a global function whether in a static method or not?C ++如何有条件地调用全局函数,无论是否在静态方法中?
【发布时间】: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++


【解决方案1】:

您可以考虑使用可变参数宏来重载带有可选参数的宏名称。因此参数的数量将区分全局和对象断言。它可能是一个虚拟参数或对象特定的东西。

Optional Parameters with C++ Macros

【讨论】:

  • 我考虑过要求用户传入“this”指针以记录对象元数据,这样可以解决问题。最终目标是避免用户/编码人员必须做任何明确的事情,并且它会正常工作。
【解决方案2】:

这不是很漂亮,但是您可以将静态成员函数放入缺少 DoAssert 成员的基类中。

【讨论】:

  • 有趣的想法!不幸的是,引擎中有许多基础游戏对象的子类可能有也可能没有静态方法。
猜你喜欢
  • 1970-01-01
  • 2011-01-13
  • 2010-11-19
  • 2013-03-20
  • 2023-03-30
  • 2012-03-01
  • 2020-06-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多