对于std :: pair,c ++重载operator []

时间:2012-03-02 00:37:49

标签: c++ overloading std operator-keyword std-pair

我使用多对值进行了大量工作:std::pair<int, int> my_pair。有时我需要在my_pair.firstmy_pair.second上执行相同的操作。

如果我可以my_pair[j]并循环 j = 0,1 ,我的代码会更顺畅。 (我正在避免使用数组,因为我不想打扰分配内存,而且我会广泛使用pair和其他内容。

因此,我想为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,但我想我错过了一些......

3 个答案:

答案 0 :(得分:7)

  1. 您不能将operator []重载为非成员
  2. 您无法定义尚未在类定义中声明的成员函数
  3. 您无法修改std :: pair
  4. 的类定义

    这是非会员实施:

    /// @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);
    

    请注意,我们需要两个版本:一个用于只读对,另一个用于可变对。

    不要害怕大量使用非会员功能。正如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 lambdas并且至少有点安全,那就不是太笨拙了,因为它没有可能超出界限。

答案 1 :(得分:2)

您无法像这样向现有类添加函数。你当然不能对std命名空间中的事情做这件事。

所以你应该定义自己的包装类:

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

public:
    int &operator[](int i) { return (i == 0) ? p[0] : p[1]; }
    // etc.
};

答案 2 :(得分: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);