具有类的常用实例的 C++ 命名空间,如 Unity 的 Vector3.Up

C++ namespace with common used instances of the class like Unity's Vector3.Up

提问人:Marco Gonçalves 提问时间:2/16/2023 最后编辑:Marco Gonçalves 更新时间:2/16/2023 访问量:89

问:

我有一个命名空间 Vector2(在另一个命名空间 CHIM 中),它表示一个 2D Vector。我们多次使用零向量 ( [0, 0] ),因此,我们希望能够写出类似这样的东西:

Vector2 a = CHIM::Vector2::ZERO;

这是Unity游戏引擎中常用的东西。 问题是,类 Vector2 [显然] 不能包含其类型的成员,因为它的大小是无限的。

我们目前通过制作一个静态函数来解决这个问题,该函数返回一个表示零向量的 Vector2。但这使得代码必须运行一个函数:

Vector2 a = CHIM::Vector2::ZERO();

正如你所看到的,它有点冗长,尽管结果是一样的。

有什么办法可以做到这一点吗?

[编辑]

下面是代码外观的简单示例:

#define CHIM_API 

namespace CHIM {

union CHIM_API Vector2 {


    struct { float x, y; };
    struct { float u, v; };
    struct { float w, h; };
    struct { float width, height; };
    float vec[2];

    Vector2() : x(0), y(0) {};
    Vector2(float x, float y) : x(x), y(y) {}

    inline const static Vector2 ZERO = {0, 0};  // ERROR:  Variable has incomplete type 'const Vector2'
   
    // Rest of the code
}
C++ unity-game-engine 命名空间

评论


答:

2赞 273K 2/16/2023 #1

不要不完整的数据类型inline

namespace CHIM {

union Vector2 {
    struct { float x, y; };
    struct { float u, v; };
    struct { float w, h; };
    struct { float width, height; };
    float vec[2];

    Vector2() : x(0), y(0) {};
    Vector2(float x, float y) : x(x), y(y) {}

    const static Vector2 ZERO;
};
}

在 .cpp 中定义。const CHIM::Vector2 CHIM::Vector2::ZERO;

请参阅静态成员

但是,如果声明使用 constexpr 或内联(自 C++ 17 起)说明符,则必须将成员声明为具有完整类型。

评论

0赞 Marco Gonçalves 2/16/2023
那奏效了,非常感谢!只有两件事:1)当你在.cpp中说定义时,你只是意味着'''常量静态向量2 ZERO = {0, 0};'''对吧?2)为什么在这种情况下我们不能使用内联?
0赞 273K 2/16/2023
因为这是一个语言规则。请参阅参考资料。
0赞 user17732522 2/16/2023
没错,这里需要行外定义。如果它是一个模板,那么 / 可以定义内联成员。inlineconstexpr