4

次のコードを検討してください (これは単なる例です)。

#include <iostream>
#include <type_traits>
#include <array>

template <
class Crtp, 
class Vector = typename std::decay<decltype(std::declval<Crtp>().data())>::type, 
class Scalar = typename std::decay<decltype(std::declval<Crtp>().data(0))>::type
>
struct Base
{;};

template <
class Vector = std::array<double, 3>, 
class Scalar = typename std::decay<decltype(std::declval<Vector>()[0])>::type
>
struct Derived
: public Base<Derived<Vector, Scalar>>
{
    Vector _data;
    inline Vector& data() {return _data;}
    inline const Vector& data() const {return _data;}
    inline Scalar& data(const unsigned int i) {return _data[i];}
    inline const Scalar& data(const unsigned int i) const {return _data[i];}
};

int main()
{
    Derived<> d;
    return 0;
}

次のエラーが返されます。

main.cpp: In instantiation of 'struct Derived<>':
main.cpp:28:14: required from here
main.cpp:16:8: error: invalid use of incomplete type 'struct Derived<>'
main.cpp:16:8: error: declaration of 'struct Derived<>'

これを解決する方法はありますか (typedef を使用せず、テンプレートのみを使用)?

4

1 に答える 1

1

Derivedテンプレートの引数推定が に対して行われるときは完全ではないので、これはかなり厄介ですBase。私は明白な答え - パスVectorScalar明示 - は不十分だと思います。どうですか:

template <template <class, class> class Derived,
          class Vector, class Scalar>
struct Base {};

template <class Vector, class Scalar>
struct Derived : Base<Derived, Vector, Scalar> {};

なぜ使用しないという奇妙な制限があるのtypedefですか? 私は見つけます:

template <class Vector>
using ScalarTypeOf =
  typename std::decay<decltype(std::declval<Vector>()[0])>::type;

template <class Crtp>
using VectorTypeOf =
  typename std::decay<decltype(std::declval<Crtp>().data())>::type;

template <class Crtp>
struct Base {
  using Vector = VectorTypeOf<Crtp>;
  using Scalar = ScalarTypeOf<Vector>;
};

template <class Vector>
struct Derived : public Base<Derived<Vector>> {
  using Scalar = ScalarTypeOf<Vector>;
};

もう少し読みやすくするために。

于 2013-07-17T03:42:12.023 に答える