[英]Can one make move_iterator from istream_iterator?
考虑以下代码:
typedef istream_iterator<char> char_itr ;
char_itr eos;
string ll("some text here");
istringstream line_in(ll);
char_itr start(line_in);
move_iterator<char_itr> mstart(start); // !!!
move_iterator<char_itr> meos(eos);
vector<char> vc(mstart, meos);
上面的代码因为行(!!!)而无法编译:
error C2440: 'return' : cannot convert from 'const char' to 'char &&'
但是如果你分别用start
和eos
替换mstart
和meos
(常规迭代器),代码就会编译。 为什么我不能做move_iterators
?
编辑:对于那些想知道为什么我想从流/字符串中移动一个字符的人。 实际问题涉及比char
更复杂的数据类型,应避免从字符串复制。 char
仅仅是为了简单起见而使用,以呈现导致错误的机制。
今年早些时候在std-discussion新闻组上对此进行了讨论: https : //groups.google.com/a/isocpp.org/forum/#!topic/ std-discussion/ h7jGY95j1oc
共识似乎是istream_iterator::reference
是T const&
强制执行InputIterator
合约; 也就是说,防止用户写*it = value;
。 不幸的是,这也阻止了从缓存值移动。
如上所述TC,将解决方案发布到LWG2106 ,代码将编译; 不幸的是因为move_iterator::reference
将是T const&&
它会默默地做错误的事情,很可能会调用你的类型的拷贝构造函数。
由于istream_iterator
在递增时修改缓存的值,因此(从语言POV)合法到const_cast
返回对T&
引用。 不幸的是(再一次)在这里没有帮助,因为没有简单的方法在istream_iterator
和move_iterator
之间插入const_cast
。
可能的解决方法:
reference
typedef编写自己的istream_iterator
; move_iterator
执行const_cast
; const_cast
迭代器; 后一种选择非常简单:
template<class T>
struct mutable_wrapper {
T mutable value;
operator T&() const { return value; }
};
// ...
using itr = std::istream_iterator<mutable_wrapper<MyType>>;
例子 。
看看istream_iterator::reference
,我们看到它是T const &
。 取消引用迭代器为我们提供了这样的参考。 但是为了能够从某些东西转移,那些东西需要可以修改。 这就是错误消息试图告诉你的内容。
您可以通过放置一些自定义迭代器从istream_iterator
创建一个move_iterator
,该迭代器在其间保持内部(非常量)存储。
但是你为什么要从istream_iterator
转移? 这些是单通道迭代器 ,因此几乎没有内部存储空间。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.