可以从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);
上述代码不会由于行(!!!)而编译:
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-constreference
typedef; - write your own
move_iterator
performingconst_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屋!