【发布时间】:2017-03-13 09:32:21
【问题描述】:
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)之后,这种迭代器没有右值构造函数,而几乎所有其他类型都有它?
您可以争辩说,由于迭代器是可复制的并且拥有一个引用,如果被引用的对象不再存在(std::reference_wrapper 也禁用了右值构造),您可能会得到未定义的行为,但这也可能发生在左值引用。
毕竟这是用户的土地责任。
【问题讨论】:
-
为什么在这里使用单数
ostream迭代器,而不是istringstream迭代器?您还可以在没有参数的情况下调用my_it。您的示例似乎无效。不过,我理解潜在的问题。 -
stackoverflow.com/q/17246720/560648 和 stackoverflow.com/q/37546443/560648 是关于此的问题,但答案没有说明为什么。真的,你应该在相关委员会的邮件列表中询问。 m.reddit.com/r/cpp/comments/3109yn/… 更接近并给出了一些想法。在
istream_iterator rvalue,FWIW 的 Google 结果的第一页上。 -
@LightnessRacesinOrbit 我忘记了
double显式模板参数到ostream_iterator。不带参数的my_it调用创建了一个end迭代器。 -
@Peregring-lk 好吧,我做了一个simple test,至少在我尝试过的所有编译器上都可以,所以至少是这样。
-
@NathanOliver 不是吗?它通过引用而不是价值来获取它。引用的析构函数是无操作的。
标签: c++ c++11 iterator rvalue-reference