为什么我不能创建流迭代器?
Why I cannot create a stream iterator?
我应该创建一个看起来像流迭代器 class 以便在递增我的 class.
的对象时我可以从输入流中读取
我已经这样做了:
template<class T>
struct istrm_it{
istrm_it() = default;
istrm_it(std::istream& in) :
in_(in), val_(T()) {
in_ >> val_;
}
T val_;
std::istream& in_ = std::cin;
istrm_it& operator++() { in >> val_; return *this; };
istrm_it& operator++(int) { in_ >> val_; return *this; };
T operator*() { return val_; }
bool operator==(const istrm_it& rhs)const { return in_ == rhs.in_; }
bool operator!=(const istrm_it& rhs) const{ return in_ != rhs.in_; }
};
int main(){
istrm_it<int> it(std::cin), e;
cout << *it << endl; // ok
it++; // ok read the next value from the nput stream
vector<int> vi;
while (it != e) // the problem here
vi.push_back(*it++);
for (auto i : vi)
std::cout << i << ", ";
std::cout << std::endl;
std::cout << std::endl;
}
我得到的是:Severity Code Description Project File Line Suppression State
Error C2678 binary '!=': no operator found which takes a left-hand operand of type 'std::istream' (or there is no acceptable conversion)
问题在于比较 in_ != rhs.in_
(以及 in_ == rhs.in_
)。您无法比较 streams.
相反,您需要保留某种 "is end iterator" 或 "is at end-of-file" 状态,该状态在您到达文件末尾时设置,默认情况下在默认构造的迭代器对象中设置.
As @Some programmer dude
: Stream 对象既不能被复制、赋值也不能被比较。
如果你想让它用于某些教育目的,那么你可以将另一个成员添加到你的 class istrm_iter
中,以跟踪它绑定到的流状态和 [=31] =] 运算符比较那里的迭代器是否它们的内部状态是好的所以如果它们都好那么它们是相等的并且当它们是 off-end
时发生这种情况否则它们不相等:
不将迭代器绑定到流的默认构造函数应该会使内部状态变坏。
并且 ++
应该在每个输入运算符之后检查流是否命中 EOF
或报告了 IO 错误,从而将状态设置为错误。这使得它等于用默认构造函数构造的那个(作为尾端迭代器)。
这里有一个简单的建议:
template<class T>
struct istrm_it {
istrm_it() = default;
istrm_it(std::istream& in) :
in_(in), val_(T()),
is_good_(true) {
in_ >> val_;
}
bool is_good_ = false;
T val_ = T{};
std::istream& in_ = std::cin;
istrm_it& operator++() { in_ >> val_; if (!in_) is_good_ = false; return *this; };
istrm_it& operator++(int) { in_ >> val_; if (!in_) is_good_ = false; return *this; };
T operator*() { return val_; }
bool operator==(const istrm_it& rhs) const {
return is_good_ && rhs.is_good_ || !is_good_ && !rhs.is_good_;}
bool operator!=(const istrm_it& rhs) const{ return !(operator==(rhs)); }
};
主要是:
int main(){
istrm_it<int> it(std::cin), e;
cout << *it << endl;
vector<int> vi;
while (it != e)
vi.push_back(*it++);
for (auto i : vi)
std::cout << i << ", ";
std::cout << std::endl;
}
不行。 N.B 这只是我知道的一个例子,实际上要模仿标准库定义的 class 需要很多东西。
我应该创建一个看起来像流迭代器 class 以便在递增我的 class.
的对象时我可以从输入流中读取我已经这样做了:
template<class T>
struct istrm_it{
istrm_it() = default;
istrm_it(std::istream& in) :
in_(in), val_(T()) {
in_ >> val_;
}
T val_;
std::istream& in_ = std::cin;
istrm_it& operator++() { in >> val_; return *this; };
istrm_it& operator++(int) { in_ >> val_; return *this; };
T operator*() { return val_; }
bool operator==(const istrm_it& rhs)const { return in_ == rhs.in_; }
bool operator!=(const istrm_it& rhs) const{ return in_ != rhs.in_; }
};
int main(){
istrm_it<int> it(std::cin), e;
cout << *it << endl; // ok
it++; // ok read the next value from the nput stream
vector<int> vi;
while (it != e) // the problem here
vi.push_back(*it++);
for (auto i : vi)
std::cout << i << ", ";
std::cout << std::endl;
std::cout << std::endl;
}
我得到的是:Severity Code Description Project File Line Suppression State
Error C2678 binary '!=': no operator found which takes a left-hand operand of type 'std::istream' (or there is no acceptable conversion)
问题在于比较 in_ != rhs.in_
(以及 in_ == rhs.in_
)。您无法比较 streams.
相反,您需要保留某种 "is end iterator" 或 "is at end-of-file" 状态,该状态在您到达文件末尾时设置,默认情况下在默认构造的迭代器对象中设置.
As @Some programmer dude
: Stream 对象既不能被复制、赋值也不能被比较。
如果你想让它用于某些教育目的,那么你可以将另一个成员添加到你的 class istrm_iter
中,以跟踪它绑定到的流状态和 [=31] =] 运算符比较那里的迭代器是否它们的内部状态是好的所以如果它们都好那么它们是相等的并且当它们是 off-end
时发生这种情况否则它们不相等:
不将迭代器绑定到流的默认构造函数应该会使内部状态变坏。
并且 ++
应该在每个输入运算符之后检查流是否命中 EOF
或报告了 IO 错误,从而将状态设置为错误。这使得它等于用默认构造函数构造的那个(作为尾端迭代器)。
这里有一个简单的建议:
template<class T>
struct istrm_it {
istrm_it() = default;
istrm_it(std::istream& in) :
in_(in), val_(T()),
is_good_(true) {
in_ >> val_;
}
bool is_good_ = false;
T val_ = T{};
std::istream& in_ = std::cin;
istrm_it& operator++() { in_ >> val_; if (!in_) is_good_ = false; return *this; };
istrm_it& operator++(int) { in_ >> val_; if (!in_) is_good_ = false; return *this; };
T operator*() { return val_; }
bool operator==(const istrm_it& rhs) const {
return is_good_ && rhs.is_good_ || !is_good_ && !rhs.is_good_;}
bool operator!=(const istrm_it& rhs) const{ return !(operator==(rhs)); }
};
主要是:
int main(){
istrm_it<int> it(std::cin), e;
cout << *it << endl;
vector<int> vi;
while (it != e)
vi.push_back(*it++);
for (auto i : vi)
std::cout << i << ", ";
std::cout << std::endl;
}
不行。 N.B 这只是我知道的一个例子,实际上要模仿标准库定义的 class 需要很多东西。