は、次のことを考えてみましょう:構文解析はどのように機能するのですか?型を完全または不完全にする要素は何ですか?
template <typename Alg> class AlgorithmTraits;
template <class Alg>
struct Heuristic {
using Neighbor = typename AlgorithmTraits<Alg>::Generator::Neighbor;
};
template <class Alg, template <class> class HType>
struct Generator {
using Neighbor = int;
HType<Alg> h_;
};
template <class Alg>
using GeneratorPolicy = Generator<Alg, Heuristic>;
template <template <class> class InitialHeuristic_,
template <class> class Generator_> class Astar;
template <template <class> class InitialHeuristic_,
template <class> class Generator_>
struct AlgorithmTraits<Astar<InitialHeuristic_, Generator_>> {
using MyAlgorithm = Astar<InitialHeuristic_, Generator_>;
using InitialHeuristic = InitialHeuristic_<MyAlgorithm>;
using Generator = Generator_<MyAlgorithm>;
};
template <template <class> class InitialHeuristic_,
template <class> class Generator_>
class Astar {
using InitialHeuristic = typename AlgorithmTraits<Astar>::InitialHeuristic;
using Generator = typename AlgorithmTraits<Astar>::Generator;
//InitialHeuristic h_; // version 1 (does not compile)
Generator g_; // version 2 (compiles)
};
int main() {
Astar<Heuristic, GeneratorPolicy> a; (void)a;
return 0;
}
コメントで「バージョン2」と表記Astar
クラスの定義にラインを見てください。 Astar
がmain
のようにインスタンス化された場合、メンバーg_
は、のインスタンス化であるタイプh_
を持つタイプGeneratorPolicy<Astar>
です。しかし、Heuristic
のNeighbor
エイリアスの宣言では、GeneratorPolicy<Astar>
が完了する必要があります。私はそれが完全ではないと思います。なぜなら、コンパイラは今すぐ解析中ですからです。したがって、なぜコードがコンパイルされるのか混乱しています。
P.S. GeneratorPolicy<Astar>
が完了したと答えると、バージョン1がどのようにコンパイルされないのか説明してください。そのバージョンのg++ 5.4.0
のエラー出力は次のようになります。
temp.cpp: In instantiation of ‘struct Generator<Astar<Heuristic, GeneratorPolicy>, Heuristic>’:
temp.cpp:17:72: required from ‘struct Heuristic<Astar<Heuristic, GeneratorPolicy> >’
temp.cpp:43:22: required from ‘class Astar<Heuristic, GeneratorPolicy>’
temp.cpp:48:39: required from here
temp.cpp:23:16: error: ‘Generator<Alg, HType>::h_’ has incomplete type
HType<Alg> h_;
^
temp.cpp:16:8: note: declaration of ‘struct Heuristic<Astar<Heuristic, GeneratorPolicy> >’
struct Heuristic {
EDIT:アマデウスへおかげで、ここでは簡単なバージョンです:
template <typename Alg>
struct Generator;
template <typename Alg> struct Heuristic {
using Neighbor = typename Generator<Alg>::Neighbor;
};
template <typename Alg> struct Generator {
using Neighbor = int;
Heuristic<Alg> h;
};
int main()
{
Heuristic<int> x; // Version 1 - compile error
//Generator<int> x; // Version 2 - compile fine
(void)x;
}
は、しかし、私はまだはっきりと理由をバージョン2つのコンパイルを理解していません良い。
コードは非常に複雑で読みにくく、把握が難しいです。 – sigy
"不完全な型"は、通常、 'class Incomplete;'のような宣言と定義しか持たない 'class'や' struct'のような型です。 –