可以从istream_iterator中生成move_iterator吗
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 &&'
但是,如果将mstart
和meos
分别替换为start
和eos
(常规迭代器(,则代码将编译。为什么我不能制作move_iterators
?
编辑:对于那些想知道我为什么要从流/字符串中移动字符的人。实际问题涉及比char
更复杂的数据类型,应该避免从字符串中复制。为了简单起见,使用char
来呈现导致错误的机制。
今年早些时候,std讨论新闻组上对此进行了讨论:https://groups.google.com/a/isocpp.org/forum/#!主题/标准讨论/h7jGY95j1oc
一致认为istream_iterator::reference
是T const&
,以执行InputIterator
合同;即防止用户写入CCD_ 11。不幸的是,这也阻止了从缓存值中移动。
如上所述,将决议发布到LWG2106,代码将编译;不幸的是,因为move_iterator::reference
将是T const&&
,所以它会默默地做错误的事情,很可能会调用您类型的复制构造函数。
由于istream_iterator
在递增时会修改缓存的值,因此它(从语言POV(对于const_cast
(返回的对T&
的引用(是合法的。不幸的是(再次(,这在这里没有帮助,因为在istream_iterator
和move_iterator
之间没有简单的方法插入const_cast
。
可能的解决方案:
- 编写您自己的
istream_iterator
,使用非常量的reference
typedef - 编写自己的
move_iterator
执行const_cast
- 编写一个插入式CCD_ 24迭代器
- 在值类型周围使用可变包装器
后一种选择出奇地简单:
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
?这些是单遍迭代器,因此可能几乎没有内部存储。
- 瓦尔格林德:数学函数"Conditional jump or move depends on uninitialised value(s)"
- Usages of std::move
- 在C++中对T*类型执行std::move的意外行为
- 关于std::move的使用,是否有编译警告
- 我应该实现右值推送功能吗?我应该使用std::move吗
- 通过实例理解std::move及其目的
- 使用仅使用一次的变量调用的复制构造函数.这可能是通过调用move构造函数进行编译器优化的情况吗
- 是否可以在 C++03 中定义'move-and-swap idiom'等效项
- 返回一个带有 std::move 的对象并链接函数
- '[](std::list& list)<int>{return std::move(list)}(list)' 是否保证将 'list' 留空?
- 为什么字符串的 move() 会改变内存中底层数据的位置?
- 当 std::move 与 C 样式数组或不移动对象时会发生什么
- 在调试模式下引发C++ "deque iterator not dereferencable"异常
- std::iterator::reference 必须是引用吗?
- 为什么当我为 for(auto& it : myUnorderedMap) {... = std::move(it.second)} 时,我会得到一个 const 引用?
- 添加自定义析构函数时,Move 构造函数在派生类中消失
- 将向量从 N1 缩小到 N2 项,而不触发默认构造函数并仅使用 move 语义
- CPP 中的瓦尔格林德和记忆泄漏:"Conditional jump or move depends on uninitialised values"
- std::move a const std::vector in a lambda capture
- Clang Modules 与 std <iterator> 和 <boost/move/iterator.hpp 的交互>