3

在 C++ 中如何告诉编译器 Ogre::Vector3 IS_SAME_AS SomeOtherLIB::Vector3 ?我觉得..在像 c++ 这样不是结构类型的语言中,但在某些情况下它是有意义的。

通常作为游戏开发人员使用 4+ 提供排序或他们自己的 Vector3 实现的库时。代码中充斥着 ToOgre、ToThis、ToThat 转换函数。那是很多 Float3 复制,首先不应该发生。

在 C++ 或任何其他语言中,我们不必将一种类型转换(复制)到另一种类型,这本质上是相同的。但是 C++ 中的任何解决方案,因为大多数优秀的 gamedevs 库都是用于 c/c++ 的。

4

4 回答 4

18

如果您使用模板,则可以定义采用任何类型参数的函数,只要在该类型上定义了必要的操作即可。例子:

class Foo { void quack() {} };
class Bar { void quack() {} };
class Baz {};

template<typename Duck>
void f(Duck d) {
    d.quack();
}
int main() {
    f(Foo()); // works
    f(Bar()); // works
    f(Baz()); // compile error because Baz does not have a quack method
    return 0;
}
于 2010-06-01T21:58:01.960 回答
6

虽然它不适合任何情况,但模板可以为您提供“编译时鸭子类型”

假设您有两种矢量类型:

struct Vec3A {
    float x, y, z;
};

struct Vec3B {
    float p[3];
};

您可以定义隐藏实现如何获取组件的功能模板:

template<class T> float get_x(const T&);
template<class T> float get_y(const T&);
template<class T> float get_z(const T&);

template<> float get_x<Vec3A>(const Vec3A& v) { return v.x; }
// ...
template<> float get_x<Vec3B>(const Vec3B& v) { return v.p[0]; }
// ...

有了这样的助手,您现在可以编写适用于两者的通用函数:

template<class T> float length(const T& t) {
    return std::sqrt(std::pow(get_x(t), 2), 
                     std::pow(get_y(t), 2),
                     std::pow(get_z(t), 2));
}

您还可以通过专门化实用程序来继续,例如length()出于性能或其他原因,例如,如果某个向量已经有一个成员函数为您提供长度:

template<> float length<Vec3C>(const Vec3C& v) {
    return v.length();
}
于 2010-06-01T22:10:13.350 回答
2

如果你真的确定非虚拟结构的情况,你可以做一个 reinterpret_cast。但是,最好:

  1. 执行模板化包装函数,如 sepp2k 所示
  2. 从其中一个向量继承并将转换运算符添加到另一个向量
  3. 添加一个单独的 _cast 函数来进行转换
于 2010-06-01T22:00:55.433 回答
1

Haxe是一种高度可移植的语言,具有完全可选的结构子类型:

typedef Vector3 = { x : double, y : double, z : double };

class FancyVector3 {
    public var x : double, y : double, z : double;

    function dot(Vector3 v) {
        return x * v.x + y * v.y + z * v.z;
    }

    function length() {
        return Math.sqrt(dot(this));
    }
}

Vector3 不仅是一个已经可用的结构,它还充当其他类的结构接口。这样typedef的 'd 结构可以指定函数签名以及字段。

Haxe 还有一个用于与 C++ 对话的 CFFI(尽管它仍然需要转换方法),并且已经为一些 C++ 游戏引擎以及各种低级框架提供了绑定。用纯 Haxe 编写的跨平台引擎也在开发中,针对各种 C++、Flash 和 JS(Canvas 和 WebGL)。

这可能不是您现在正在寻找的解决方案,但可能会在几年内变得更加有趣。

于 2013-04-07T01:15:33.810 回答