std::istream_iterator
是否有任何特定原因无法将流作为右值接收?
为了传递临时对象,我必须创建一个类似的函数:
template<class T, class ostream_t>
std::istream_iterator<T> my_it(ostream_t&& ostream)
{ return {ostream}; }
template<class T>
std::istream_iterator<T> my_it() { return {}; }
int main()
{
std::string file("3.45 1.23 7,56");
std::copy(my_it<double>(std::istringstream(file)), my_it<double>(),
std::ostream_iterator<double>(std::cout, " "));
}
然而,这将更方便,更短:
int main()
{
std::string file("3.45 1.23 7,56");
using my_it = std::istream_iterator<double>;
std::copy(my_it(std::istringstream(file)), my_it(),
std::ostream_iterator<double>(std::cout, " "));
}
为什么在三次标准更新(C ++ 11,C ++ 14和C ++ 17)之后,对于那种迭代器没有rvalue构造函数,几乎每种其他类型都有它?
你可以争辩说,由于迭代器是可复制的并且包含引用,如果引用的对象不再存活,你可以获得未定义的行为(std::reference_wrapper
也禁用了rvalue构造),但是也可以与左值参考一起发生。
毕竟,这是用户的土地责任。
答案 0 :(得分:-3)
我认为您的回答是page 74 of Modern C++:
例如,istream对象表示输入值流,其中一些可能已经被读取,其中一些可能稍后被读取。如果要复制一个istream,是否需要复制已经读取的所有值以及将来读取的所有值?处理这些问题的最简单方法是将它们定义为不存在。禁止复制流就是这样。
==编辑==
哦,我完全误解了你的问题!我现在明白你对临时价值的意思了。让我只粘贴你的程序的两个版本,以突出问题。
这不编译:
#include <string>
#include <iostream>
#include <iterator>
#include <sstream>
#include <algorithm>
int main()
{
std::string file("3.45 1.23 7,56");
using my_it = std::istream_iterator<double>;
std::copy(my_it(std::istringstream(file)), my_it(),
std::ostream_iterator<double>(std::cout, " "));
}
但这样做:
#include <string>
#include <iostream>
#include <iterator>
#include <sstream>
#include <algorithm>
int main()
{
std::string file("3.45 1.23 7,56");
using my_it = std::istream_iterator<double>;
std::istringstream a(file);
std::copy(my_it(a), my_it(), std::ostream_iterator<double>(std::cout, " "));
}