0

次のクラスがあるとします。

template <typename DataType, size_t Dimensions>
class Vector : public std::array<DataType, Dimensions> {
//stuff
};

template <typename DataType>
class Vector2 : public Vector<DataType, 2> {
//2d specific stuff
};

template <typename DataType, size_t Dimensions>
class Line {
public:
  Vector<DataType, Dimensions>& min();
  Vector<DataType, Dimensions>& max();

private:
  Vector<DataType, Dimensions> m_min;
  Vector<DataType, Dimensions> m_max;
};

template <typename DataType>
class Line2 : public Line<DataType, 2> {
//2d specific stuff
};

a で呼び出されたときにaではなくamin()を返す最良の方法は何ですか? 内にとを昇格させることはできますか? または、それらをオーバーライドしても、基本クラスは適切に機能しますか?max()Line2Vector2&Vector&m_minm_maxVector2Line2Line

4

3 に答える 3

0

ちょっとした更新、これは私がやったことです:

Base クラスに属する一部の関数は Vector のコピーを返す必要があったため、CRTPを使用する必要がありました。しかし、私はそのために必要なスケルトン コードが本当に好きではありませんでした。あまりにも複雑でした。

template <typename derived>
struct test_base {
  derived baz() { return *static_cast<derived *>(this); }
};

template <int N>
  struct test : public test_base<test<N>> {
};

template <>
struct test<2> : public test_base<test<2>> {
  test bar() { return *this; }
};

int main() {
  test<1> a = {};
  test<2> b = {};

  auto c = a.baz();
  auto d = b.baz();
  auto e = b.bar();

  return 0;
}

そこで、よりフラットな階層を求めて、いくつかのテンプレートのトリックに頼りました。

#include <type_traits>

template <int N>
struct test {
  void foo() {}

  template <int P=N>
  typename std::enable_if<P == 2 && P == N>::type bar() {}

  template <int P=N>
  typename std::enable_if<P == 3 && P == N>::type baz() {}
};

int main() {
  test<1> a = {};
  test<2> b = {};
  test<3> c = {};

  a.foo();
  b.foo();
  c.foo();

  b.bar();
  c.baz();

  return 0;
}

これは、よりクリーンなソリューションのように思えました。また、次のような関数を書くこともできます。

template <int P=N>
typename std::enable_if<P >= 2 && P == N>::type x() { return Base::operator[](0); }
于 2013-09-10T21:57:37.203 に答える