1

filtered_ostream_iterator述語を使用してストリームをフィルタリングするのに役立つクラスを実装し、それをテンプレート クラスとして作成しました。

template<typename T, typename Pred>
class filtered_ostream_iterator
{
    ostream& os;
    Pred _filter;

public:
    filtered_ostream_iterator(ostream & o, Pred filter): os(o),
                                                        _filter(filter) {}

    filtered_ostream_iterator& operator++()
    {
        return *this;
    }

    filtered_ostream_iterator& operator*()
    {
        return *this;
    }

    filtered_ostream_iterator& operator=(T t)
    {

        if (_filter(t))
            os << t;
        return *this;
    }
};

大丈夫ですが、今問題があります。私が使用するときはfiltered_ostream_iterator、次のように定義する必要があります。

stringstream ss1;
auto filter = [](char t){ return (t >= 'a' && t <=  'z') || (t >= 'A' && t <=  'Z'); };
filtered_ostream_iterator<char, bool (*)(char)> it1(ss1, filter); // initialization

特に見た目は良くありません<char, bool (*)(char)>。次に、型を自動的に推論できる特別な関数を作成することにしました。

template<typename Pred>
filtered_ostream_iterator<char, Pred> create_filtered_ostream_iterator(ostream& os, Pred pred)
{
    return filtered_ostream_iterator<char, Pred>(os, pred); // problem
}

そして、私は次のように使用します

auto it1 = create_filtered_ostream_iterator(ss1, filter);

ストリームで要素のタイプを指定する必要があることがわかりますが、実際にはテンプレートではありませんが、以下のコードを次のようなものに置き換えようとすると

template<typename Pred, typename T>
filtered_ostream_iterator<T, Pred> create_filtered_ostream_iterator(ostream& os, Pred pred)
{
    return filtered_ostream_iterator<T, Pred>(os, pred); // error
}

同じように使っていると

auto it1 = create_filtered_ostream_iterator(ss1, filter);

次のエラーが表示されます。

error: no matching function for call to 'create_filtered_ostream_iterator'

では、これらの問題をすべて回避するにはどうすればよいでしょうか。それとも、最初の定義のバリエーションを使用する必要があり、見た目がどれほど難しいかは気にしませんか? あなたはそれについてどう思いますか?

4

1 に答える 1

3

次のように書きます。

template <typename T, typename Pred>
filtered_ostream_iterator<T, Pred> create(std::ostream & os, Pred p)
{
    return filtered_ostream_iterator<T, Pred>(os, p);
}

使用法:

auto it = create<char>(ss1, filter);

末尾のテンプレート引数のみを推測できますが、最初の引数は好きなだけ自由に指定できます。

別の方法は、ストリームから型を推測することです。

template <typename TChar, typename TTraits, typename Pred>
filtered_ostream_iterator<typename TTraits::char_type, Pred>
create(std::basic_ostream<TChar, TTraits> & os, Pred & p)
{
    return filtered_ostream_iterator<typename TTraits::char_type, Pred>(os, p);
}

使用法:

auto it = create(ss, filter);
于 2012-10-07T13:39:29.413 に答える