c++ - 解析如何工作或者什么使类型完整或不完整?

标签 c++

考虑以下因素:

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/

相关文章:

c++ - 在基于范围的 for 中强制使用 cbegin()/cend()

C++字符串,字符串不能包含加号

c++ - 来自 OpenCV 的 VTK 相机姿势来自 solvePnP 的估计姿势

c++ - 调试版本找不到调试运行时 DLL

c++ - std::initializer_list: error C2064: term 不计算为采用 0 个参数的函数

c++ - 从数字和 C++ 中的位掩码生成数字数组

c++ - 基于带有英特尔 Vtune 放大器的挂钟时间的 C++ 程序简介

c++ - 如何配置xmlrpc-c深渊服务器主机?

c++ - Mingw x64 Windows : plugin needed to handle lto object

c++ - C 样式转换是否添加程序集(代码)或仅供编译器了解情况?