C ++或任何其他语言的可选结构类型可能性?

时间:2010-06-01 21:47:38

标签: c++ programming-languages duck-typing structural-typing

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

通常作为游戏开发人员使用提供排序或自己的Vector3实现的4个以上的库。代码中充斥着ToOgre,ToThis,ToThat转换功能。这就是很多Float3的复制,不应该在第一时间发生。

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

4 个答案:

答案 0 :(得分:17)

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

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;
}

答案 1 :(得分: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();
}

答案 2 :(得分:2)

如果您非常确定非虚拟结构,可以执行reinterpret_cast。但是,最好是:

  1. 执行模板化包装函数,如sepp2k所示
  2. 继承其中一个向量并将转换运算符添加到另一个向量
  3. 添加一个单独的_cast函数来执行转换

答案 3 :(得分: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'结构可以指定函数签名以及字段。

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

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