2

一連のイテレータを使用する独自のアルゴリズム (実際には単なる関数) を作成したいと考えています。イテレータがマップからのものである場合、データ (イテレータ->秒) の値を使用したいと考えています。イテレータがベクトルやリストのように「通常」の場合は、逆参照されたイテレータ値を使用したいだけです。

4

5 に答える 5

5

値取得のアイデアはここにあると思いますが、c++11関数のみを使用して、構造体の有無にかかわらず実装できます。

template <typename T> 
const T& get(const T& t)
{
    return t;
}

template <typename T, typename V>
const V& get(const std::pair<T,V>& t)
{
    return t.second;
}


int main()
{
    std::vector<int> v = {1};
    std::cout << get(*v.begin());

    std::cout << "\n----\n";

    std::map<int, std::string> m;
    m.insert(std::make_pair(0, "sss"));
    std::cout << get(*m.cbegin());
}
于 2012-08-16T19:30:32.787 に答える
4

関心のある値を抽出する値ゲッタークラスを作成できます。このアプローチは、sを任意のコンテナーに格納する場合は機能しないことに注意してください(マップ内かどうかに関係なく、pairすべてのsを変換します)。pair「通常の」イテレータのみを受け入れ、マップイテレータを適切に変換することを呼び出し元の仕事にする方がはるかに明確なアプローチだと思います(質問へのコメントで示唆されています)。

template<typename T>
struct get {
  static auto val(const T& t) -> const T&
  {
    return t;
  }
};

template<typename U, typename V>
struct get<std::pair<U, V>> {
  static auto val(const std::pair<U, V>& p) -> const V&
  {
    return p.second;
  }
};

// use like
get<decltype(*iter)>::val(*iter);

コンビニエンス関数は次のようになります。

template<class T>
auto getval(const T& t) -> decltype(get<T>::val(t))
{
  return get<T>::val(t);
}
于 2012-08-16T19:00:52.753 に答える
3

入力に基づいて関数をオーバーロードできます。

void foo(const std::vector<int>::iterator& it1, const std::vector<int>::iterator& it2) 
{
   //use *it
}
void foo(const std::map<int,int>::iterator& it1, const std::map<int,int>::iterator& it2)
{
   //use it->second
}

編集:

これがあなたが達成したいことに最も近いと思います:

template <typename T, typename X>
void foo(T const& x, X const& y)
{

}

template <typename T, typename S>
void foo(const typename std::map<T,S>::iterator& x, const typename std::map<T,S>::iterator& y)
{

}

int main()
{
    std::map<int,int> x;
    std::vector<int> y;
    foo(x.begin(), x.end()); //will call second version
    foo(y.begin(), y.end()); //will call first version
}
于 2012-08-16T18:52:17.743 に答える
2

特性はトリックを行う必要があります。まず、型を推測するヘルパー:

template <typename Iter>
typename iter_value<Iter>::value_type & iter_deref(Iter it)
{
    return iter_value<Iter>::deref(it);
}

必要なのは次のようなものだけです。

template <typename Iter>
class iter_value
{
    template <typename T> struct aux
    {
        typedef T type;
        static type & deref(Iter it) { return *it; }
    };
    template <typename U, typename V> struct aux<std::pair<U const, V>>
    {
        typedef V type;
        static type & deref(Iter it) { return it->second; }
    };

    typedef typename std::iterator_traits<Iter>::value_type type;

public:
    typedef typename aux<type>::type value_type;

    static value_type & deref(Iter it)
    {
        return aux<type>::deref(it);
    }
};
于 2012-08-16T19:19:11.463 に答える
1

イテレータから値を抽出する関数を作成できます。次に、イテレータの型に基づいてそれをオーバーロードできます。その関数をアルゴリズムで使用できます。のベクトルと->intsのマップを想定すると、次のようになります。stringint

int getValue(const std::vector<int>::iterator& it)
{
    return *it;
}

int getValue(const std::map<std::string, int>::iterator& it)
{
    return it->second;
}

次に、アルゴリズムは関数getValue()を使用してイテレータから値を取得できます。

于 2012-08-16T18:57:47.093 に答える