模板化的递归数据类型

str*_*cat 11 c++ templates g++ c++11

我有一个这样的递归数据类型:

template<typename T>
struct SomeType {
    std::map<T, SomeType<T>> mapping;
};

SomeType<int> foo;
Run Code Online (Sandbox Code Playgroud)

这工作得很好,但将std::mapstd::unordered_map因不完全类型编译错误的结果.我(或gcc)在某个地方犯了错误吗?或者这只是标准的一部分?

我还希望内部容器由模板参数(例如std::stackstd::queue)确定,但我无法找到一种方法,因为这需要已定义SomeType.

不完整的例子:

template<typename T, typename C = std::map<T, SomeType<[???]>>>
struct SomeType {
    C mapping;
};

SomeType<int, [???]> foo;
Run Code Online (Sandbox Code Playgroud)

我知道这可以通过运行时间接完成,但这不是我正在寻找的.

Irf*_*rfy 7

}定义的最后一个版本之前,您的课程都是不完整的.因此该mapping成员SomeType在其类型的模板参数中使用了不完整的类型.

该标准不允许这样做,并且它与一些STL容器一起运行是纯粹的运气.

你的第二个问题属于同一个答案 - 首先这样做是违法的.


Ker*_* SB 5

由于显而易见的原因,您无法使用递归默认参数定义模板。您也不能在不完整的类型上实例化标准库容器模板,因为标准是这么说的(否则它是未定义的行为)。不过,通常的 PIMPL 习惯用法可能会有所帮助:

#include <map>
#include <memory>
template <typename T> class SomeType
{
    typedef std::map<T, SomeType<T>> map_type;
    typedef std::unique_ptr<map_type> map_ptr;
    map_ptr pimpl;
public:
    SomeType() : pimpl(new map_type) { }
};
Run Code Online (Sandbox Code Playgroud)