21

私のプロジェクトでは、ストリームを特定のタイプの値に分割したいので、テンプレート関数を次のように実装します

template <typename TElem, typename TOutputIter>
TOutputIter SplitSpace(std::istream& IS, TOutputIter result)
{
    TElem elem;
    while (IS >> elem)
    {
        *result = elem;
        ++result;
    }
    return result;
}

TElem呼び出すときに型を明示的に指定する必要があるため、これは厄介だと思います。たとえば、次のように書く必要があります。

std::vector<int> v;
SplitSpace<int>(std::cin, back_inserter(v));
// I want to it to be   SplitSpace(std::cin, back_inserter(v)); 

(テンプレート)イテレータから値の型を取得しようとし、std::iterator_traits次のように使用しました:

template <typename TOutputIter>
TOutputIter SplitSpace(std::istream& IS, TOutputIter result)
{
    typename std::iterator_traits<TOutputIter>::value_type elem;
    while (IS >> elem)
    {
        *result = elem;
        ++result;
    }
    return result;
}

ただし、上記のコードは では機能しませんback_insert_iterator。名前空間back_insert_iterator/front_insert_iterator/insert_iterator内のソース コードを確認したところ、すべて.stdvalue_type/difference_type/pointer/referencevoid

これらのタイプがすべて である理由を知りたいのvoidですが、これについて何か考慮事項はありますか? 別の質問は、SplitSpace関数を呼び出すときに要素の型を明示的に指定せずに関数を実装することは可能ですか? ありがとう。

4

4 に答える 4

3

テンプレート パラメータの指定を回避する方法を探しているだけの場合は、次の方法をTElem使用できます。

template <typename TOutputIter>
TOutputIter SplitSpace(std::istream& IS, TOutputIter result)
{
    typedef typename TOutputIter::container_type::value_type TElem;

    TElem elem;
    while (IS >> elem)
    {
        *result = elem;
        ++result;
    }
    return result;
}

...もちろん、使用するふりをしている TOutputIter 型によっては、このアプローチを使用しないでください。

于 2013-04-23T10:17:01.630 に答える
2

私の知る限り、container_typeイテレータから を取得できるはずです。そこから を取得できるはずですvalue_typepairおそらく、ある時点で a に特化したいと思うでしょう。これは、パート 1 と同様に、パート 2 に答える必要があります。わからない...

于 2013-04-23T09:36:38.497 に答える