首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用于std::operator[]的operator[]重载

用于std::operator[]的operator[]重载
EN

Stack Overflow用户
提问于 2012-03-02 00:37:49
回答 3查看 2.7K关注 0票数 4

我做了很多关于值对的工作:std::pair<int, int> my_pair。有时,我需要对my_pair.firstmy_pair.second执行相同的操作。

如果我能够在my_pair[j]上执行j=0,1并在j=0,1上循环,我的代码就会平滑得多。(我避免使用数组,因为我不想麻烦地分配内存,而且我在其他事情上广泛使用pair )。

因此,我想为operator[]定义std::pair<int, int>

我不能让它工作(我不太擅长模板之类的).

代码语言:javascript
复制
#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;
}

无法编译。其他变体也失败了。

据我所知,我正在跟踪堆栈溢出操作符重载常见问题,但我想我遗漏了一些东西.

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-03-02 00:44:14

  1. 不能将operator[]重载为非会员。
  2. 不能定义未在类定义中声明的成员函数。
  3. 不能修改std::偶数的类定义

下面是一个非会员实现:

代码语言:javascript
复制
/// @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自己说的,没有必要用对象来建模所有东西,也不需要通过继承来扩展所有东西。如果您确实希望使用类,则更喜欢组合而不是继承。

你也可以这样做:

代码语言:javascript
复制
/// 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,并且由于它没有越界访问的潜力,所以它至少更安全一些,这并不难使用。

票数 8
EN

Stack Overflow用户

发布于 2012-03-02 00:42:57

不能向这样的现有类添加函数。当然,您不能对std命名空间中的内容执行此操作。

因此,您应该定义自己的包装类:

代码语言:javascript
复制
class MyPair {
private:
    std::pair<int,int> p;

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

Stack Overflow用户

发布于 2012-03-02 05:02:50

您可能应该查看一下Boost.Fusion。您可以将算法应用于序列(其中std::偶数被认为是序列)。例如,您可以这样做for_each:

代码语言:javascript
复制
std::pair<int, int> my_pair;
for_each(my_pair, [] (int i)
{
    cout << i;
});

还可以访问元素的索引,如下所示:

代码语言:javascript
复制
int sum = at_c<0>(my_pair) + at_c<1>(my_pair);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9526430

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档