我正在尝试对此进行相反的操作:
std::ostream outs; // properly initialized of course
std::set<int> my_set; // ditto
outs << my_set.size();
std::copy( my_set.begin(), my_set.end(), std::ostream_iterator<int>( outs ) );
它应该是这样的:
std::istream ins;
std::set<int>::size_type size;
ins >> size;
std::copy( std::istream_iterator<int>( ins ), std::istream_iterator<int>( ins ) ???, std::inserter( my_set, my_set.end() ) );
但是我坚持使用'end'迭代器 - 输入的交互器不能使用std :: advance,我也不能使用两个具有相同源的流......
有什么优雅的方法如何解决这个问题?当然我可以用于循环,但也许有更好的东西:)
答案 0 :(得分:3)
您可以从istream_iterator&lt; T&gt;派生 虽然使用Daemin generator method是另一种选择,但我会直接生成集合而不是使用中间向量。
#include <set>
#include <iterator>
#include <algorithm>
#include <iostream>
template<typename T>
struct CountIter: public std::istream_iterator<T>
{
CountIter(size_t c)
:std::istream_iterator<T>()
,count(c)
{}
CountIter(std::istream& str)
:std::istream_iterator<T>(str)
,count(0)
{}
bool operator!=(CountIter const& rhs) const
{
return (count != rhs.count) && (dynamic_cast<std::istream_iterator<T> const&>(*this) != rhs);
}
T operator*()
{
++count;
return std::istream_iterator<T>::operator*();
}
private:
size_t count;
};
int main()
{
std::set<int> x;
//std::copy(std::istream_iterator<int>(std::cin),std::istream_iterator<int>(),std::inserter(x,x.end()));
std::copy(
CountIter<int>(std::cin),
CountIter<int>(5),
std::inserter(x,x.end())
);
}
答案 1 :(得分:3)
使用:
std::copy( std::istream_iterator<int>(ins),
std::istream_iterator<int>(),
std::inserter(my_set, my_set.end())
);
请注意空参数:
std::istream_iterator<int>();
答案 2 :(得分:2)
Errr ... copy_n()算法?
答案 3 :(得分:2)
稍微考虑一下我不认为直接读到一个集合会起作用,因为你需要在它上面调用insert来实际添加元素(我可能会弄错,这是在早上这里)。虽然简单地看一下VS2005中的STL文档但我认为使用generate_n函数的东西应该可以工作,例如:
std::istream ins;
std::set<int> my_set;
std::vector<int> my_vec;
struct read_functor
{
read_functor(std::istream& stream) :
m_stream(stream)
{
}
int operator()
{
int temp;
m_stream >> temp;
return temp;
}
private:
std::istream& m_stream;
};
std::set<int>::size_type size;
ins >> size;
my_vec.reserve(size);
std::generate_n(my_vec.begin(), size, read_functor(ins));
my_set.insert(my_vec.begin(), my_vec.end());
希望这可以解决你的问题,或者说服你在宏观计划中没有那么糟糕。
答案 4 :(得分:1)
如何使用备用迭代器进行遍历,然后使用函数对象(或lambda)来填充容器?
istream ins;
set<int>::size_type size;
set<int> new_set;
ins >> size;
ostream_iterator<int> ins_iter(ins);
for_each(counting_iterator<int>(0), counting_iterator<int>(size),
[&new_set, &ins_iter](int n) { new_set.insert(*ins_iter++); }
);
当然这假设您有一个符合C ++ 0x的编译器。
BTW,'counting_iterator&lt;&gt;'是Boost.Iterator的一部分。
答案 5 :(得分:1)
或者你可以这样做:
my_set.insert(std::istream_iterator<int>(ins), std::istream_iterator<int>());
答案 6 :(得分:0)
(编辑:我应该更仔细地阅读这个问题......)
虽然有点怀疑,但是你可以通过在文件中输入一个“失败”第一个循环来获得大致正确的行为,然后清除流上的失败位并开始阅读更多内容。
数据,没有明确的大小,但是像这样
1 1 2 3 5 8 Fibb
美联储对下面的代码似乎做了我的意思,至少在VS2005上使用STLPort。
typedef std::istream_iterator < int, char, std::char_traits ,ptrdiff_t> is_iter; std::copy( is_iter(cin), is_iter(), inserter(my_set,my_set.end())); cin.clear(); std::cin >> instr;
答案 7 :(得分:0)
是sdg,但是当我想在该文件/流中使用其他数据结构时?我应该在这里明确地写一下,我想在这个集合之后存储另一个东西,这也是我存储大小的原因。