可以从istream_iterator中创建move_iterator吗? [英] Can one make move_iterator from istream_iterator?

查看:292
本文介绍了可以从istream_iterator中创建move_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);

上述代码不会由于行(!!!)而编译:

Above code will not compile because of line (!!!):

error C2440: 'return' : cannot convert from 'const char' to 'char &&'

但如果您替换 mstart meos 分别使用 start eos (常规迭代器),代码将编译。为什么我无法使 move_iterators

But if you replace mstart and meos with start and eos, respectively (regular iterators), the code will compile. Why I can't make move_iterators?

EDIT:那些想知道为什么我想从一个流/字符串中移动一个字符。实际问题涉及比 char 更复杂的数据类型,应避免从字符串进行复制。 char 仅仅是为了简单起见,以表示导致错误的机制。

For those wondering why I would like to move a character from a stream/string. Actual problem involves more complex data type than char which copying from a string should be avoided. char was used just for the sake of simplicity, to present the mechanism causing error.

推荐答案

今年早些时候在std-discussion新闻组上讨论过这个问题: https://groups.google.com/a/isocpp.org/forum/#!topic/std-discussion/h7jGY95j1oc

共识似乎是 istream_iterator :: reference T const& code> InputIterator contract;也就是防止用户写 * it = value; 。不幸的是,这也阻止从缓存的值移动。

The consensus appears to be that istream_iterator::reference is T const& to enforce the InputIterator contract; that is, to prevent users writing *it = value;. Unfortunately, this also prevents moving from the cached value.

请将该解决方案发布到 LWG2106 的代码后进行编译;不幸的是因为 move_iterator :: reference 会是 T const&&& ,它会默默做错事,

As T.C. mentioned above, post the resolution to LWG2106 the code will compile; unfortunately because move_iterator::reference will be T const&& it will silently do the wrong thing, most likely invoking the copy constructor of your type.

由于 istream_iterator 在递增时修改缓存的值,因此它是POV)合法到 T& 的返回引用 const_cast 。不幸的是(再次)在这里没有帮助,因为没有简单的方法插入 const_cast 之间的 istream_iterator code> move_iterator 。

Since istream_iterator modifies the cached value when incremented, it is (from a language POV) legal to const_cast the returned reference to T&. Unfortunately (again) that doesn't help here as there's no easy way to interpose a const_cast between the istream_iterator and move_iterator.

可能的解决方案:


  • 编写您自己的 istream_iterator ,其中包含非const 引用 typedef;

  • 写您自己的 move_iterator 执行 const_cast ;


  • write your own istream_iterator, with a non-const reference typedef;
  • write your own move_iterator performing const_cast;
  • write an interposing const_cast iterator;
  • use a mutable wrapper around the value type.

后面的选项非常简单:

template<class T>
  struct mutable_wrapper {
    T mutable value;
    operator T&() const { return value; }
  };
// ...
using itr = std::istream_iterator<mutable_wrapper<MyType>>;

示例

这篇关于可以从istream_iterator中创建move_iterator吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆