Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/.htaccess/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ c+中的循环类型依赖关系+;使用容器迭代器(GCC失败,而MSVC正常)_C++_G++_Unordered Map - Fatal编程技术网

C++ c+中的循环类型依赖关系+;使用容器迭代器(GCC失败,而MSVC正常)

C++ c+中的循环类型依赖关系+;使用容器迭代器(GCC失败,而MSVC正常),c++,g++,unordered-map,C++,G++,Unordered Map,我编写的原始代码在microsoft的编译器中运行良好,但没有使用gcc(4.7.4)进行编译: 以下是简化的代码: // test.cpp #include <unordered_map> using namespace std; struct order_rec; typedef unordered_map<int, order_rec> placed_orders_t; typedef placed_orders_t::iterator placed_order_

我编写的原始代码在microsoft的编译器中运行良好,但没有使用gcc(4.7.4)进行编译: 以下是简化的代码:

// test.cpp
#include <unordered_map>
using namespace std;

struct order_rec;
typedef unordered_map<int, order_rec> placed_orders_t;
typedef placed_orders_t::iterator placed_order_iterator;
typedef unordered_map<int, placed_order_iterator> book_list_t;
typedef book_list_t::iterator book_list_iterator;
struct order_rec
{
    int a;
    book_list_iterator bi;
};

int main()
{
    book_list_t test1;
    order_rec test2;
}

我认为这是一个编译器问题。但一般来说,它不应该工作,因为当您使用
typedef unordered\u map placed\u orders\t
它需要知道
order\u rec
的大小,这样它就可以相应地分配内存,而在您的情况下,内存是未知的,因此可以使用
order\u rec*
代替
order\u rec
或者在使用它之前将
struct order\u rec
的定义移动到。当你写作时:

struct order_rec;
typedef unordered_map<int, order_rec> placed_orders_t;
typedef placed_orders_t::iterator placed_order_iterator;
struct order\u rec;
typedef无序地图下订单;
typedef下订单迭代器下订单迭代器;
这需要实例化
已下订单
,这需要实例化
无序地图
<代码>订单记录此时不完整。从[res.on.functions]:

特别是,在以下情况下,效果是未定义的:[……]如果在实例化模板组件时将不完整类型(3.9)用作模板参数,除非该组件特别允许

标准库中的某些类模板允许使用不完整的类型(如
唯一的ptr
向量
),但
无序的映射
不是其中之一,因此其效果未定义。未能编译是允许的结果。请注意,
map
,即使您的代码已编译,也是如此


您必须将
placed\u orders\u t::mapped\u type
作为可在此上下文中使用的类型。也许
std::unique\u ptr

不是一个很好的解决方案,但我们可以更改
order\u rec
并尽早声明

struct  book_list_iterator;
struct order_rec
{   
    int a;
    vector    <book_list_iterator> bi;
};


为什么不能在typedefing
下订单之前定义
order\u rec
?@cocarin它有一个成员
book\u list\u迭代器bi
图书列表的迭代器,其中
图书列表
是itr=>
下单的映射
,其中
下单
是int=>
下单
的映射。换句话说,在完全声明
book\u list\u迭代器
之前,无法定义order\u rec。您需要真正的
迭代器
,还是一个指针就足够了?我这样问是因为它起作用:
typedef pair*placed\u order\u指针。但是我想您需要一个迭代器,它将有助于您的问题,发布从gcc失败编译生成的精确错误消息输出。Fwiw,它同样以叮当声3.8.0在编译时呕吐。谢谢。clang在其转储中更具描述性,但本质上是相同的。在紧要关头,我想你可以把你的
bi
作为
std::unique\u ptr
而不是现在这样。无论如何,在存放所有这些迭代器时应该非常小心,因为底层序列的更改可能会很快使它们失效。还要注意的是,std::map工作得很好。在内部,IMO的所有内容都用作指向订单的指针。当实例化
placed\u orders\u t
时,只需完全定义
order\u rec
类型定义不分配任何内容,因此此时不需要大小。下面一行,查找
::iterator
似乎是问题所在。您的观点是正确的,但在您的案例中,您也使用了它的迭代器,它只能为已知类型声明。@AaronMcDaid这就是我指定的
::iterator
触发错误,这是不应该发生的IMO@VikashKesarwani我非常确定,如果指针指向某个前向声明的结构,类的typedef将起作用。在内部,无序映射impl应该使用指向
order\u rec
的指针。另外,请注意,它与std::map一起工作,毫无意义地争辩说它因某种原因无效(我认为我这样做是有效的)。可能不是未定义的,但未指定?@EdgarRokyan不,未定义。是的,似乎是这样。
unordered\u map
中的一些代码似乎在某处使用了pair::second\u类型,这意味着必须完全指定order\u rec。我想说这是g++中libstdc++中的一个bug,不必要的代码可能会触发不必要的禁止。@Pavel这不是libstdc++或gcc或clang中的bug。@Barry我需要查看并深入研究他们的stl代码,以了解它发生的位置和原因,可能是一些遗留问题触发了这个限制。从某种意义上说,这是一个bug,它让我感到困扰,而不是它违反了规范;)有趣的方法:)我会试试。我认为,我可以有效地删除向量,只需使用指向新的
book\u list\u t::iterator
struct book\u list\u iterator
副本的指针,它可以聚合迭代器,而不是从迭代器继承它……所有这些都可以有效地归结为
typedef无序的映射
我需要手动
新建
/
删除
订单,您甚至可以使用
typedef unordered\u map
。我只是用
vector
作为一种懒散的方法来避免原始指针,并且必须
new
/
删除
/
使你共享
/
使你独一无二
。当然,这确实意味着我们需要确保
向量始终只有一个元素
I
new
仅在插入记录时使用一次(我有专门的代码用于第一次插入),因此,它可以绕过不必要的限制,这些限制来自无序映射的impl from g++值得注意的是,这是因为
vector
明确允许不完整的类型。
struct  book_list_iterator;
struct order_rec
{   
    int a;
    vector    <book_list_iterator> bi;
};
typedef unordered_map<int, order_rec> placed_orders_t;
typedef placed_orders_t::iterator placed_order_iterator;
typedef unordered_map<int, placed_order_iterator> book_list_t;

struct  book_list_iterator : public book_list_t::iterator
{
};