我有这样的代码
std::ifstream file(filename, std::ios_base::in);
if(file.good())
{
file.imbue(std::locale(std::locale(), new delimeter_tokens()));
for(auto& entry : std::istream_iterator<std::string>(file))
{
std::cout << entry << std::endl;
}
}
file.close();
其中std::istream_iterator<std::string>
和 begin()
定义end()
如下
template<class T>
std::istream_iterator<T> begin(std::istream_iterator<T>& stream)
{
return stream;
}
template<class T>
std::istream_iterator<T> end(std::istream_iterator<T>& stream)
{
return std::istream_iterator<T>();
}
这也是Mark Nelson在 Dobb 博士的文章中所写的内容。唉,代码无法在我的 Visual Studio 2012 上编译并显示错误消息
错误 C3312:找不到类型“std::istream_iterator<_Ty>”的可调用“开始”函数
和
错误 C3312:找不到类型“std::istream_iterator<_Ty>”的可调用“结束”函数
问题:有什么我没有注意到的,编译器中的错误(不太可能,但以防万一)或者......嗯,有什么想法吗?
正如Xeo
所建议的那样,这个问题得到了很大的清理。为了提供更多背景和参考,这与我在 Stackoverflow 上的另一个问题有关,我想知道如何使基于行的解析比通常的循环更干净。从互联网上进行了一些编码和检查,我有一个工作草图如下
std::ifstream file(filename, std::ios_base::in);
if(file.good())
{
file.imbue(std::locale(std::locale(), new delimeter_tokens()));
for(auto& entry : istream_range<std::string>(file)
{
std::cout << entry << std::endl;
}
}
file.close();
但我试图纠正一些轻微的障碍。我认为写成无法编译的代码看起来会更自然,而不像
for(auto& entry : istream_range<std::string>(file)
请注意不同的迭代器。demeter_tokens的定义就像Nawaz在这里展示的那样(代码不重复),而istream_range的定义就像代码综合博客中的一样。我认为 begin 和 end 实现应该可以工作,正如前面提到的代码合成博客文章中所宣传的那样
最后一条规则(回退到独立的 begin() 和 end() 函数)允许我们以非侵入方式将现有容器调整为基于范围的 for 循环接口。
因此,我的问题具有所有(ir)相关背景。