4

我经常使用成对的值:std::pair<int, int> my_pair. 有时我需要对 和 执行相同的my_pair.first操作my_pair.second

如果我能做my_pair[j]并循环 j=0,1 ,我的代码会更流畅。(我避免使用数组,因为我不想费心分配内存,而且我pair广泛使用其他东西)。

因此,我想定义 operator[]for 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 运算符重载 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);

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

不要害怕自由地使用非成员函数。正如 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 lambda,那么使用它并不会太笨拙,并且至少更安全一些,因为它没有可能越界访问。

于 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 回答