gpt4 book ai didi

templates - 在 typedef 中实例化具有不完整类型的列表

转载 作者:行者123 更新时间:2023-12-01 11:52:32 25 4
gpt4 key购买 nike

我在编译 llvm 时遇到问题。问题是我当前的编译器(clang + libc++)试图在定义模板参数之前实例化模板。下面是代码示例:

// ----- TYPEDEFS -----
class NodeEntry;
class EdgeEntry;

typedef std::list<NodeEntry> NodeList;
typedef std::list<EdgeEntry> EdgeList;

typedef NodeList::iterator NodeItr; // line 39
typedef NodeList::const_iterator ConstNodeItr;

typedef EdgeList::iterator EdgeItr;
typedef EdgeList::const_iterator ConstEdgeItr;

typedef std::list<EdgeItr> AdjEdgeList;

typedef AdjEdgeList::iterator AdjEdgeItr;

class NodeEntry {
private:
AdjEdgeList adjEdges;
...
};

class EdgeEntry {
private:
AdjEdgeItr node1AEItr, node2AEItr;
...
};

编译器的错误是这样的:
error: field has incomplete type 'PBQP::Graph::NodeEntry'

/Developer/Extras/llvm/include/llvm/CodeGen/PBQP/Graph.h:39:13: note: in instantiation of template class
'std::__1::list<PBQP::Graph::NodeEntry, std::__1::allocator<PBQP::Graph::NodeEntry> >' requested here
typedef NodeList::iterator NodeItr;
^
/Developer/Extras/llvm/include/llvm/CodeGen/PBQP/Graph.h:31:11: note: forward declaration of 'PBQP::Graph::NodeEntry'
class NodeEntry;

据我所知,编译器尝试实例化 std::list<NodeEntry>为了得到迭代器。这将失败,因为 NodeEntry 尚未定义。当然,EdgeEntry 正在使用 NodeEntry,反之亦然。

显而易见的问题是:我该如何解决?
教育问题是:为什么编译器在定义类型时尝试实例化模板?难道不应该等到我们对列表做一些事情吗?

谢谢。

最佳答案

如果你想保证支持不完整的类型,最好的办法是创建 unique_ptr对他们来说:

typedef std::list<std::unique_ptr<NodeEntry>> NodeList;
typedef std::list<std::unique_ptr<EdgeEntry>> EdgeList;
过去多次 std::list<incomplete_type>只会工作。但是对于 C++11 和 noexcept规范,越来越有可能需要一个完整的类型,只是为了 noexcept规范可以验证。
C++11 保证 unique_ptr<incomplete_type>shared_ptr<incomplete_type>会起作用,尽管有严格的限制。例如无论在哪里 ~unique_ptr()执行时,类型必须在那里完成。但是您通常可以将此类代码概述到源代码中,然后在该点#include 完整类型。 unique_ptr<incomplete_type>shared_ptr<incomplete_type>是 C++11 std::lib 中唯一保证可以使用不完整类型的类模板。其他一切都是未定义的行为:
[res.on.functions]/p2/b5:

In particular, the effects are undefined in the following cases:

...

  • if an incomplete type (3.9) is used as a template argument when instantiating a template component, unless specifically allowed for that component.

如果由于某种原因 std::list不需要拥有指向不完整类型的指针,则 std::list<NodeEntry*>效果会更好。您可能还想使用 vector 来娱乐。而不是 list因为在周围移动指针(甚至 unique_ptr 的)的成本相对较小。

关于templates - 在 typedef 中实例化具有不完整类型的列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10065384/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com