我做过一些类似的研究:
告诉我,如果我误解了一些。
我试图从文件中输入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)
我不知道我现在能做什么...... 希望有人能给我一些建议。 感谢。
答案 0 :(得分:2)
要了解问题所在,我们必须看一下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
,请参阅typedef 根据[temp.dep.type] / 8,两种类型都是相关的。
对于表达式A >> B
以及任何其他函数调用,首先查找函数的名称(此处:operator>>
) - &gt; 名称查找,然后,从找到的函数集(重载)中,选择并调用最可行的 - &gt; 重载决议。
对于操作员,查找成员和非成员函数(例如您的操作员)。
在这种情况下,涉及的类型是相关的,因此名称查找的特殊规则适用[temp.dep.res] / 1:
在解析依赖名称时,会考虑以下来源的名称:
- 在模板定义时可见的声明。
- 来自实例化上下文(14.6.4.1)和定义上下文中与函数参数类型相关联的名称空间的声明。
您的运算符已在全局命名空间中定义,该命名空间既不与std::basic_istream
也不与std::pair
相关联。因此,名称分辨率找不到您的运算符,并且行(A)中表达式的重载分辨率失败。
这将解释clang 3.2的错误消息:
stream_iterator.h:120:17:错误:二进制表达式的操作数无效('istream_type'(又名'basic_istream&lt; char,std :: char_traits&gt;')和'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&);
这就是AFAIK,只是在表达式operator>>
操作rvalue(如istream_obj >> value
)的情况下调用另一个get_istream() >> value
的包装器。
这与您的问题无关(并且令人困惑)。
两个解决方法:
std::pair
,以便您可以在与该包装类型相关联的命名空间中定义operator>>