3

C++ でコンパイラに Ogre::Vector3 IS_SAME_AS SomeOtherLIB::Vector3 を伝える方法は? 私はそれを感じます..構造型ではないc ++のような言語では、それが理にかなっている場合があります。

通常、ソートまたは独自の Vector3 実装を提供する 4 つ以上のライブラリを使用するゲーム開発者として。コードには、ToOgre、ToThis、ToThat 変換関数が散らばっています。それは、最初に発生するべきではない多くの Float3 コピーです。

C ++または他の言語では、ある型から別の型に変換(コピー)する必要はありませんが、これは本質的に同じです。ただし、ほとんどの優れたゲーム開発ライブラリは c/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

どんな状況にも適していませんが、テンプレートは「コンパイル時のダックタイピング」を提供できます。

2 つのベクトル型があるとします。

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. ベクトルの 1 つから継承し、変換演算子を他のベクトルに追加します。
  3. 変換を行う別の _cast 関数を追加します
于 2010-06-01T22:00:55.433 に答える