4

私は値のペアで多くの作業を行います: std::pair<int, int> my_pair. と の両方で同じ操作を実行する必要がある場合がありmy_pair.firstますmy_pair.second

j=0,1my_pair[j]をループして 実行できれば、私のコードははるかにスムーズになります。(メモリの割り当てに煩わされたくないので、配列の使用を避けています。他のものにも広く使用しています)。pair

したがって、 forを定義 したいと思います。operator[]std::pair<int, int>

そして、私はそれを機能させることができません(私はテンプレートなどにあまり得意ではありません)...

#include <utility>
#include <stdlib.h>

template <class T1> T1& std::pair<T1, T1>::operator[](const uint &indx) const
{
  if (indx == 0)
    return first;
  else
    return second;
};

int main()
{
// ....
return 0;
}

コンパイルに失敗します。他のバリエーションも同様に失敗します。

私が知る限り、私はStack Overflow operator overloading FAQに従っていますが、何かが足りないと思います...

4

3 に答える 3

8
  1. operator[] を非メンバーとしてオーバーロードすることはできません
  2. クラス定義で宣言されていないメンバー関数を定義することはできません
  3. std::pair のクラス定義を変更することはできません

非メンバーの実装は次のとおりです。

/// @return the nth element in the pair. n must be 0 or 1.
template <class T>
const T& pair_at(const std::pair<T, T>& p, unsigned int n)
{
    assert(n == 0 || n == 1 && "Pair index must be 0 or 1!");
    return n == 0 ? p.first: p.second;
}

/// @return the nth element in the pair. n must be 0 or 1.
template <class T>
T& pair_at(std::pair<T, T>& p, unsigned int index)
{
    assert(index == 0 || index == 1 && "Pair index must be 0 or 1!");
    return index == 0 ? p.first: p.second;
}

// usage:
pair<int, int> my_pair(1, 2);
for (int j=0; j < 2; ++j)
    ++pair_at(my_pair, j);

2 つのバージョンが必要であることに注意してください。1 つは読み取り専用ペア用で、もう 1 つは可変ペア用です。

非メンバー関数を自由に使用することを恐れないでください。Stroustrup 自身が言ったように、すべてをオブジェクトでモデル化したり、継承によってすべてを拡張したりする必要はありません。クラスを使用したい場合は、継承より合成を優先してください。

次のようなこともできます。

/// Applies func to p.first and p.second.
template <class T, class Func>
void for_each_pair(const std::pair<T, T>& p, Func func)
{
    func(p.first);
    func(p.second);
}

/// Applies func to p.first and p.second.
template <class T, class Func>
void for_each_pair(std::pair<T, T>& p, Func func)
{
    func(p.first);
    func(p.second);
}

// usage:
pair<int, int> my_pair(1, 2);
for_each_pair(my_pair, [&](int& x){
    ++x;
});

これは、C++11 ラムダを使用している場合に使用するのにそれほど扱いにくくはなく、範囲外にアクセスする可能性がないため、少なくとも少しは安全です。

于 2012-03-02T00:44:14.503 に答える
3

このように既存のクラスに関数を追加することはできません。stdそして、名前空間内のものに対してそれを行うことはできません。

したがって、独自のラッパー クラスを定義する必要があります。

class MyPair {
private:
    std::pair<int,int> p;

public:
    int &operator[](int i) { return (i == 0) ? p[0] : p[1]; }
    // etc.
};
于 2012-03-02T00:42:57.643 に答える
0

おそらくBoost.Fusionをチェックする必要があります。アルゴリズムをシーケンスに適用できます (std::pair はシーケンスと見なされます)。たとえば、次のように for_each を実行できます。

std::pair<int, int> my_pair;
for_each(my_pair, [] (int i)
{
    cout << i;
});

次のように要素のインデックスにアクセスすることもできます。

int sum = at_c<0>(my_pair) + at_c<1>(my_pair);
于 2012-03-02T05:02:50.213 に答える