模板递归类型
我有这样一个递归类型:模板递归类型
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
。
The standard does not allow this, and it is pure luck that it works with some STL containers.
你的第二个问题属于相同的答案下 - 它是非法的这样做摆在首位。
嗯。不幸的是,我不理解这篇文章中关于为什么'std :: map
如果这需要解释,我建议打开一个聊天室,这并不难,只是不适合评论部分...现在,我该如何明确地打开一个聊天室关于这... – Irfy 2012-03-25 16:31:11
让我们在这里聊天:http:///chat.*.com/rooms/9282/stl-with-incomplete-types – Irfy 2012-03-25 16:34:00
出于显而易见的原因,您无法定义具有递归默认参数的模板。您也不能在不完整类型上实例化标准库容器模板,因为标准是这样说的(否则它是未定义的行为)。通常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) { }
};
boost :: container库为大多数STL类型提供了替代方案,这些类型允许不完整类型的递归容器。它目前不提供unmarked_map – mark 2012-03-26 07:47:02
@mark:谢谢,这很好理解! – 2012-03-26 08:03:55
虽然你不能使用不完全类型与容器,你可以用智能指针做到这一点。 虽然你不能创建未定义类型参数模板类型,你可以使用一些技巧,在这里:
template<typename T, template <typename U, typename V, typename... Args> class Container = std::unordered_map >
struct SomeType {
Container<T, std::unique_ptr<SomeType> > mapping;
};
是否有可能更改第一行,使Container的默认值为std :: vector? – 2015-01-25 11:36:44
@NielsLohmann,从技术上讲,你可以编写'template
标准库容器模板需要实例化他们完整的类型;一切都是未定义的行为。你必须忍受这一点。不过,您可以使用pimpl解决方案来解决这个问题。 – 2012-03-25 13:45:44
@KerrekSB是这样吗?该死,我经常编写n-ary树,其节点是用'std :: vector children'来实现的。 –
2012-03-25 13:46:42
@KonradRudolph:好的,你必须确保在实例化时类型已经完成。这可能是一个微妙的问题。 – 2012-03-25 13:57:51