0

ファイルから要素のリストを読み取り/逆シリアル化しようとしています(そして、それらのいくつかを除外します)。この目的でイテレータを使用するのは便利な方法ですか?

私の現在の試みは

#include <boost/iterator/iterator_adaptor.hpp>
class ReadIterator : public boost::iterator_adaptor<ReadIterator, Elem *, boost::single_pass_traversal_tag>
{
public:
    explicit ReadIterator(const char *filename) : reader(filename)  {}

private:
    friend class boost::iterator_core_access;

    void increment() {
         this->base_reference() = reader.readNext();
    }

    Reader reader;
};

これはメモリの割り当てを適切に解除しません (たとえば、readNew は新しい Elem へのポインタを返します)。これを行う正しい方法は何ですか? また、そのようなイテレータを実際にどのように使用するのでしょうか?どのように終了を決定できますか? または、イテレータを使用するよりも良いアプローチはありますか?

4

3 に答える 3

4

これを行う簡単な方法は、 std::istream_iterator を使用することです

std::vector<YourObjectClass>    data;

std::remove_copy_if(std::istream_iterator<YourObjectClass>(file),
                    std::istream_iterator<YourObjectClass>(),
                    std::back_inserter(data),
                    YourFilter
                   );

標準アルゴリズムは、フィルター ファンクターが true を返す場合、オブジェクト (タイプ YourObjectClass) を入力からコピーfileし、ベクターに配置します。data

唯一の条件は次のとおりです。

  • YourObjectClass には入力ストリーム演算子が必要です
  • YourFilter は、YourObjectClass のオブジェクトの operator() をオーバーロードするか、タイプ YourObjectClass のパラメーターを取る関数である必要があります。

簡単な作業例:

  • 私のオブジェクトは線です。
  • 文字「A」で始まる行を除外します

例:

#include <vector>
#include <string>
#include <fstream>
#include <iterator>
#include <algorithm>

struct Line
{
    std::string   data;
};
std::istream& operator>>(std::istream& stream, Line& line)
{
    return std::getline(stream, line.data);
}
struct AFilter
{
    bool operator()(Line const& line) const
    {
        return line.data.size() > 0 && line.data[0] == 'A';
    }
};

int main()
{
    std::ifstream       file("Plop");
    std::vector<Line>   data;

    std::remove_copy_if(std::istream_iterator<Line>(file),
                        std::istream_iterator<Line>(),
                        std::back_inserter(data),
                        AFilter()
                       );
}
于 2011-04-19T05:44:47.233 に答える
1

要素への生のポインターを返すのではなく、readNext()ポインターへの参照カウントがゼロになったときにリソースを自動的に解放する参照カウントされたスマートポインターを返すように呼び出しを構築できますか?それか、ポインタをフェッチして戻す方法を見つける必要があります。そうすればdelete、次の呼び出しを介してメモリを割り当てる前にreadNext()、ポインタを呼び出すことができますincrement()

「終了」に関しては、この場合にできることはReader、ファイルの終了またはその他の終了シナリオに到達したかどうかを検出するテストをクラスで行うことです。持っている場合はfalseを返し、そうでない場合はtrueを返します。例えば:

bool increment()
{
    if (reader.not_end_of_file())
    {
        this->base_reference() = reader.readNext();
        return true;
    }

    return false;
}

これincrement()で、ある種のループを呼び出すことができ、関数がfalseを返すため、ファイルの終わりまたはその他の終わりに到達したことがわかります。

于 2011-04-19T05:06:23.777 に答える
1

この目的のためにイテレータを使用しても問題ありません。istream_iteratorただし、既存のものが目的のために機能しないという兆候はありません。少なくともほとんどの場合、operator>>単一の要素に対して for を記述し、 を使用std::istream_iteratorしてファイルからそれらの要素のリストを読み取ることができます。

于 2011-04-19T05:26:33.493 に答える