考虑以下因素:
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;
}
请查看 Astar
定义中的行注释中将该类标记为“版本 2”。当Astar
实例化为 main
,成员(member)g_
类型为GeneratorPolicy<Astar>
,其中有一个成员 h_
类型是 Heuristic
的实例化。然而,似乎Neighbor
的声明别名 Heuristic
应该要求 GeneratorPolicy<Astar>
是完整的。我认为它不完整,因为编译器现在正在解析它。因此,我对代码编译的原因感到困惑。
附注如果你回答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 {
编辑:感谢 Amadeus,这是一个更简单的版本:
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 编译得很好。
最佳答案
你的代码很难理解。所以,我做了一个更简单的版本:
template <typename T>
struct Bar;
template <typename T>
struct Foo
{
using a = typename Bar<T>::Type;
};
template <typename T>
struct Bar
{
using Type = int;
Foo<T> x;
};
int main()
{
//Foo<int> x; // Version 1 - compile error
Bar<int> x; // Version 2 - compile fine
(void)x;
}
当您想在定义完成之前使用类型时,就会出现不完整类型。在版本 1 中,您尝试定义 Foo<int>
同时想在Bar<int>
中使用它
对于版本 2,您正在定义 Bar<int>
,然后定义 Foo<int>
仅使用 Bar<int>::Type
,很容易完成定义。
关于c++ - 解析如何工作或者什么使类型完整或不完整?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39575841/