我有一个这样的递归数据类型:
template<typename T>
struct SomeType {
std::map<T, SomeType<T>> mapping;
};
SomeType<int> foo;
这工作正常,但更换 std::map
同 std::unordered_map
由于类型不完整导致编译错误。我(或gcc)在某个地方犯了错误吗?或者这只是标准的一部分?
我还希望通过模板参数确定内部容器(比如 std::stack
和 std::queue
),但我无法找到一种方法,因为这将需要已定义SomeType。
不完整的例子:
template<typename T, typename C = std::map<T, SomeType<[???]>>>
struct SomeType {
C mapping;
};
SomeType<int, [???]> foo;
我知道这可以通过运行时间接完成,但这不是我正在寻找的。
在决赛前的任何地方你的课程都是不完整 }
它的定义。所以 mapping
成员使用的是不完整类型 SomeType
在其类型的模板参数中。
该标准不允许这样做,并且它与一些STL容器一起运行是纯粹的运气。
你的第二个问题属于同一个答案 - 首先这样做是违法的。
出于显而易见的原因,您无法使用递归默认参数定义模板。您也无法在不完整类型上实例化标准库容器模板,因为标准会这样说(否则它是未定义的行为)。但是,通常的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) { }
};
虽然您不能将不完整的类型与容器一起使用,但您可以使用智能指针来完成。
虽然您无法使用未定义的类型参数创建模板类型,但您可以在此处使用一些技巧:
template<typename T, template <typename U, typename V, typename... Args> class Container = std::unordered_map >
struct SomeType {
Container<T, std::unique_ptr<SomeType> > mapping;
};