重载istream_iterator ----无法将左值绑定到"std::basic_istream<char>&&"
Overloading istream_iterator ---- cannot bind lvalue to ‘std::basic_istream<char>&&’
我做了一些研究,比如:
- 重载操作符<<:无法将左值绑定到' std::basic_ostream&& '
- 无法将' std::basic_ostream '左值绑定到' std::basic_ostream&& '
- 错误:无法将' std::basic_ostream '左值绑定到' std::basic_ostream&& '
如果我误解了什么,告诉我。
我试图从文件中输入std::pair,我想使用std::istream_iterator>
下面是代码:
std::ifstream in("file.in");
std::map<int, int> pp;
pp.insert((std::istream_iterator<std::pair<int, int> >(in)),
std::istream_iterator<std::pair<int, int> >());
我做了如下的重载:
std::istream & operator>>(std::istream & in, std::pair<int, int> & pa)
{ in >> pa.first >> pa.second; return in; }
std::istream & operator>>(std::istream && in, std::pair<int, int> & pa)
{ in >> pa.first >> pa.second; return in; }
错误提示:
In file included from /usr/include/c++/4.8/iterator:66:0,
from No_12.cpp:7:
/usr/include/c++/4.8/bits/stream_iterator.h: In instantiation of ‘void std::istream_iterator<_Tp, _CharT, _Traits, _Dist>::_M_read() [with _Tp = std::pair<int, int>; _CharT = char; _Traits = std::char_traits<char>; _Dist = long int]’:
/usr/include/c++/4.8/bits/stream_iterator.h:70:17: required from ‘std::istream_iterator<_Tp, _CharT, _Traits, _Dist>::istream_iterator(std::istream_iterator<_Tp, _CharT, _Traits, _Dist>::istream_type&) [with _Tp = std::pair<int, int>; _CharT = char; _Traits = std::char_traits<char>; _Dist = long int; std::istream_iterator<_Tp, _CharT, _Traits, _Dist>::istream_type = std::basic_istream<char>]’
No_12.cpp:23:59: required from here
/usr/include/c++/4.8/bits/stream_iterator.h:121:17: error: cannot bind ‘std::istream_iterator<std::pair<int, int> >::istream_type {aka std::basic_istream<char>}’ lvalue to ‘std::basic_istream<char>&&’
*_M_stream >> _M_value;
^
In file included from /usr/include/c++/4.8/iostream:40:0,
from /files/Nutstore/000/CPPWorkSpace/SHUCourse/DataStructures/BinarySearchTree/20130514/src/BinarySearchTree.hpp:6,
from /files/Nutstore/000/CPPWorkSpace/SHUCourse/DataStructures/BinarySearchTree/20130514/BinarySearchTree:3,
from No_12.cpp:1:
/usr/include/c++/4.8/istream:872:5: error: initializing argument 1 of ‘std::basic_istream<_CharT, _Traits>& std::operator>>(std::basic_istream<_CharT, _Traits>&&, _Tp&) [with _CharT = char; _Traits = std::char_traits<char>; _Tp = std::pair<int, int>]’
operator>>(basic_istream<_CharT, _Traits>&& __is, _Tp& __x)
我不知道我现在能做什么…希望有人能给我一些建议。谢谢。
要了解问题所在,我们必须看一下istream_iterator
的示例实现(问题源于标准的要求,这里隐式显示):
template < class T, class CharT, class Traits, class Distance >
class istream_iterator
{
/* ... */
typedef std::basic_istream<CharT, Traits> istream_type;
istream_type* stored_istream_ptr;
T value;
public:
/* ... */
istream_iterator& operator++()
{
*stored_istream_ptr >> value; // (A)
return *this;
}
T const& operator*() const
{
return value;
}
/* ... */
};
在(A)行中,操作符应用于依赖类型的对象:
-
value
为T
型 -
stored_istream_ptr
为istream_type
类型,参见typepedef
根据[temp. deep .type]/8,这两种类型都是依赖的。
对于表达式A >> B
以及任何其他函数调用,首先查找函数的名称(这里:operator>>
) -> 名称查找,然后,从找到的函数集合(重载)中选择最可行的并调用-> 重载解析。
对于操作符,查找成员函数和非成员函数(如操作符)。
在这种情况下,所涉及的类型是依赖的,因此name查找的特殊规则应用[temp. deep .res]/1:
在解析依赖名称时,考虑来自以下来源的名称:
- 在模板定义处可见的声明。
- 与实例化上下文(14.6.4.1)和定义上下文的函数参数类型相关联的命名空间的声明。
操作符已经在全局命名空间中定义,它既不与std::basic_istream
也不与std::pair
关联。因此,name解析找不到操作符,重载解析(A)行表达式失败。
这就解释了clang 3.2的错误信息:
stream_iterator.h:120:17:错误:无效的操作数二进制表达式('istream_type'(又名'basic_istream <Char,>') and 'std::pair')
*_M_stream >> _M_value; ~~~~~~~~~~ ^ ~~~~~~~~
它解释了为什么变通方法有效。
另一方面,g++似乎只显示了通过名称解析发现的一个重载及其拒绝它的原因(而clang++则显示了通过名称解析发现的所有重载以及每个被拒绝的原因)。g++显示的可能是"最合适的":
template< class CharT, class Traits, class T >
basic_istream<CharT,Traits>& operator>>(basic_istream<CharT,Traits>&&, T&);
在表达式istream_obj >> value
操作右值(如get_istream() >> value
)的情况下,它只是一个包装器来调用另一个operator>>
。
这与你的问题无关(而且令人困惑)。
两个解决方法:
- 使用包装器类型来包装
std::pair
,这样您就可以在与该包装器类型相关的名称空间中定义operator>>
- 在命名空间std中注入操作符(不推荐??)
- 将无符号char*转换为std::istream*C++
- 使用std::istream::peek()总是安全的吗
- istream std::cin如何修改自定义istream缓冲区
- 如何将QByteArray转换为std::istream或std::ifstream?
- 为什么 Clang std::ostream 写一个 std::istream 无法读取的双精度?
- 如何使 std::istream 从键盘获取输入(如 std::cin)?
- 如何为缺少预定义运算符而不扩展命名空间"std"的标准类型定义运算符>> (istream &, ...)?
- 我可以使用istream_iterator将<char>一些 istream 内容复制到 std::string 中吗?
- 错误:与"运算符>>"不匹配(操作数类型为"std::istream
- 为什么 std::istream::gcount 返回的字符比预期的多一个字符
- 错误:无法将"std::istream {aka std::basic_istream<char>}"lvalue 绑定到"std::basic_istream&<char>&
- 将 istream 转换为 ifstream 时将 std::cin 传递到参数时出现问题
- std :: iStream到未签名的数值,如何检测负值
- 是否可以覆盖 std::istream 读取方法?
- 没有运算符匹配这些操作数;操作数类型为: std::istream >> const char [5]
- 此功能希望从std :: istream解析该功能的输入格式
- 包装 std::istream 时出现问题,移动后unique_ptr不为空
- 为什么std :: istream ::忽略丢弃字符
- 如何从 std::istream 加载 wxXml文档?
- 没有运算符">>"匹配这些操作数操作数操作数类型为: std::istream >>双*