2010-09-06 41 views
1

我使用Boost.Range为这些数据传递一些数据和容器类。数据被加载到不同的线程中,并且在某些情况下可能尚未准备好。在这种情况下,容器使用默认的iterator_range进行初始化,因此包含单数迭代器。我正在做数据容器的分配和复制(因此是iterator_ranges)。但是,iterator_range拷贝构造函数调用begin()和end(),它会在原始单数时声明。因此,不可能复制空的数据容器。将boost :: iterator_range指定为单数范围

有什么办法可以避免这个限制吗?

为什么这个限制被实现?下面的工作很好,不应该范围行为类似?

typedef std::vector<int>::iterator iterator; 
iterator it; // Singular 
iterator it2 = it; // Works 

boost::iterator_range<iterator> range; // Singular 
boost::iterator_range<iterator> range2 = range; // Asserts in debug, but why? 

回答

3

如果“作品”,你的意思是,那是“不与我目前的编译器版本和调用选项炸毁”,指定一个单一的迭代器可能的“工作”。 实际上,代码

typedef std::vector<int>::iterator iterator; 
iterator it; // Singular 
iterator it2 = it; // Works 

导致不确定的行为,所以你到你的编译器中可能发生什么的冲动。

C++标准是这样说的关于它(段[lib.iterator.requirements]/5):

[...]大多数表达式的结果是不确定的对于奇异值;唯一的例外是将非奇异值赋值给保存奇异值的迭代器。在这种情况下,奇异值的覆盖方式与任何其他值相同。可引用的和过去的最终值总是非单一的。

所以,最后范围工作类似于单个迭代器。它只是不按你喜欢的方式工作。
我认为最好的方法是在数据尚未准备好时使用空范围(用非奇异迭代器显式构造),而不是单一范围。

+0

有趣的是,我不知道这是一个限制 - 并没有看到效果。你知道这种行为的原因吗?对于GCC和MSVC来说,它似乎可以正常工作,因为我们一直在我们的应用程序中执行此操作...:/ – larsmoa 2010-09-06 13:03:24

+0

未定义行为的原因是它甚至不需要为普通指针工作。当您查看单数指针值时,实现可能会陷入陷阱。 GCC和MSVC编译器没有任何优势,并生成允许读取f无效指针值的代码。 – 2010-09-06 13:19:02

+0

读取代码时,也很容易认为第二个迭代器已初始化。 – UncleBens 2010-09-06 14:39:00