Fle*_*exo 23 c++ iterator stl istream-iterator
我构建了一个最小的工作示例来显示我使用STL迭代器遇到的问题.我正在使用istream_iterator以下内容读取floatss(或其他类型)std::istream:
#include <iostream>
#include <iterator>
#include <algorithm>
int main() {
float values[4];
std::copy(std::istream_iterator<float>(std::cin), std::istream_iterator<float>(), values);
std::cout << "Read exactly 4 floats" << std::endl; // Not true!
}
Run Code Online (Sandbox Code Playgroud)
这将读取所有可能的floatss,直到EOF为values固定大小,4,所以现在显然我想限制范围以避免溢出并准确读取/最多4个值.
使用更多"正常"迭代器(即RandomAccessIterator),提供begin+4的不是你要做的结束:
std::copy(begin, begin+4, out);
Run Code Online (Sandbox Code Playgroud)
准确阅读4个元素.
如何做到这一点std::istream_iterator?显而易见的想法是将呼叫更改std::copy为:
std::copy(std::istream_iterator<float>(std::cin), std::istream_iterator<float>(std::cin)+4, values);
Run Code Online (Sandbox Code Playgroud)
但(相当可以预见)这不编译,没有候选人operator+:
g++ -Wall -Wextra test.cc
test.cc: In function ‘int main()’:
test.cc:7: error: no match for ‘operator+’ in ‘std::istream_iterator<float, char, std::char_traits<char>, long int>(((std::basic_istream<char, std::char_traits<char> >&)(& std::cin))) + 4’
Run Code Online (Sandbox Code Playgroud)
有什么建议?是否有正确的"STLified"前C++ 0x方法来实现这一目标?显然我可以把它写成for循环,但我想在这里学习一些关于STL的东西.我半想知道滥用std::transform或std::merge等以某种方式实现这一功能,但我不能完全看到如何做到这一点.
ild*_*arn 14
当您请求非C++ 0x解决方案时,这里有一个使用std::generate_n和生成器函数而不是std::copy_n迭代器的替代方法:
#include <algorithm>
#include <string>
#include <istream>
#include <ostream>
#include <iostream>
template<
typename ResultT,
typename CharT = char,
typename CharTraitsT = std::char_traits<CharT>
>
struct input_generator
{
typedef ResultT result_type;
explicit input_generator(std::basic_istream<CharT, CharTraitsT>& input)
: input_(&input)
{ }
ResultT operator ()() const
{
// value-initialize so primitives like float
// have a defined value if extraction fails
ResultT v((ResultT()));
*input_ >> v;
return v;
}
private:
std::basic_istream<CharT, CharTraitsT>* input_;
};
template<typename ResultT, typename CharT, typename CharTraitsT>
inline input_generator<ResultT, CharT, CharTraitsT> make_input_generator(
std::basic_istream<CharT, CharTraitsT>& input
)
{
return input_generator<ResultT, CharT, CharTraitsT>(input);
}
int main()
{
float values[4];
std::generate_n(values, 4, make_input_generator<float>(std::cin));
std::cout << "Read exactly 4 floats" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
如果你愿意,你可以结合使用这个生成器boost::generator_iterator来使用生成器作为输入迭代器.
Igo*_*nko 13
看一眼 std::copy_n
| 归档时间: |
|
| 查看次数: |
3990 次 |
| 最近记录: |