【发布时间】:2013-01-15 09:04:07
【问题描述】:
我有一个表示字符序列的类,我想为它实现一个operator >>。我的实现目前看起来像这样:
inline std::istream& operator >>(std::istream& in, seq& rhs) {
std::copy(
std::istream_iterator<char>(in),
std::istream_iterator<char>(),
std::back_inserter(rhs));
// `copy` doesn't know when to stop reading so it always also sets `fail`
// along with `eof`, even if reading succeeded. On the other hand, when
// reading actually failed, `eof` is not going to be set.
if (in.fail() and in.eof())
in.clear(std::ios_base::eofbit);
return in;
}
但是,可以预见的是以下失败:
std::istringstream istr("GATTACA FOO");
seq s;
assert((istr >> s) and s == "GATTACA");
特别是,一旦我们到达“GATTACA FOO”中的空间,复制停止(预期)并在istream 上设置故障位(也是预期的)。然而,就seq而言,读取操作实际上是成功的。
我可以使用std::copy 对此进行建模吗?我也想过改用istreambuf_iterator,但这实际上并不能解决这个特殊问题。
此外,对输入“GATTACAFOO”的读取操作应该失败,因为该输入不代表有效的 DNA 序列(这是我的类所代表的)。另一方面,在 C++ 中从输入 42foo 中读取 int 实际上 成功 所以也许我应该将每个有效前缀都视为有效输入?
(顺便说一句,如果使用显式循环,这将相当简单,但我试图避免显式循环以支持算法。)
【问题讨论】:
-
如果循环比算法更简单(因为否则你不会问这个问题),那么就用一个该死的循环。可维护性。
-
@Cat 我没有说“更直接”。事实上,我声称当使用适当的算法时(如果存在适当的序列适配器),算法解决方案总是比使用循环更直接。
-
您可以使用模板,并且您可以以某种方式找到一种方法来使用多重继承、线程和您可以梦想的任何东西,但这只会让您的生活变得更加艰难,并且不会给您带来任何明显的好处.那么,为什么要强迫自己使用明显不适合手头任务需求的迭代器和算法呢?保持简单,使用那个简单的循环并继续解决真正的问题。不要用 15 行变通方法来搞乱您的项目,以获取一个旨在光滑和优雅的库解决方案。
-
@Arne 哇,吃冰镇药,伙计。我没有做任何你指责我的事情。我明确地问是否我的方法完全合适。但是,如果你认为这种方法“显然 [不] 合适”,那么我认为你不能做出太多贡献。否则为什么首先存在输入迭代器适配器?
-
@KonradRudolph 对不起,如果我夸大了那个。我的意思是:如果您必须努力获得序列适配器,那么算法不会更直接。在您的情况下,您必须解析输入以验证它。解析不适合普通的迭代算法,所以我怀疑你会在
<algorithm>中找到任何合适的东西。
标签: c++ io istream istream-iterator