2016-11-24 146 views
0

我想知道如何去创建一个重载的括号运算符,它会提供std :: list中的元素位置。std :: list的重载括号运算符

班里列表声明如下:

std::list<Stimulation*> configuration; 

重载括号运算符声明:

std::list<Stimulation*>::operator[](const int); 

我会的数字,括号运算符的确定指标会去如下:

std::list<Stimulation*>::operator[](const int position) 
{ 
    auto i = configuration.begin(); 
    return i + position; 

    ***OR*** 

    std::list<Stimulation*>::iterator i = configuration.begin(); 
    return i + position; 
} 

我是新来的这个概念,所以任何帮助将是欣赏这样做的适当方式。我需要在这种情况下专门使用一个列表,因为我知道其他容器包含括号操作符作为库的一部分。再次感谢您的耐心和时间。

+0

有一个原因,为什么没有'列表'的括号操作符。这是因为需要从元素到元素,所以O(n)访问。你必须循环使用'for',计算你迭代的元素数量。 –

+0

你不能那样做。 –

+0

雅我读了,但我得到的这个规范是要求,所以我不知道什么是确切的。 –

回答

4

std::list元件不连续内存,不像std::vector元素,这就是为什么没有[]运营商的存在,因为这将是低效的,这不是为什么名单的制作。

但是,作为练习,您可以使用for循环来实现它。这是我的幼稚的做法,缺乏const版本,并与一个断言失败时出界:

#include <list> 
#include <iostream> 
#include <cassert> 

using namespace std; 

class MyList : public list<int> 
{ 
public: 

    int &operator[](int pos) 
    { 
     int count=0; 
     for (auto &it : *this) 
     { 
      if (count==pos) { return it;} 
      count++; 
     } 
    assert(false); 
    } 
}; 


int main() 
{ 
    MyList l; 
    l.push_back(1); 
    l.push_back(2); 
    l.push_back(3); 
    l.push_back(4); 
    cout << l[2] << endl; 
    return 0; 
} 

访问时间是非常糟糕的,如果元素在列表(O(N))结束,因为你不能添加位置list::begin()

我想你可以“缓存”最后一个询问偏移量&迭代器,所以如果调用者要求偏移+ 1(这在程序中很常见),你可以在不从头开始恢复的情况下前进。

注意:刚刚看到有关std::advance的评论。没有在那里使用(不知道它)。

+0

这更多的是我一直在寻找的感谢。本课以非正统的方式做事,真正理解我猜测的事情的理论方面,而不一定是正确的方法。欣赏时间。 –

+1

知道如何去做这样的事情是很有趣的,是的。我的一位前同事有想在定制字符串类上定义除法运算符以将目录与文件名连接起来。结果非常可读:'dirname/basename',而它与分区无关。 –

+0

你肯定是有趣的,它肯定让你想到你可以得到一种语言实现的多种方式和想法,可能有。再次感谢! –