【问题标题】:difference between foo[i] and foo->at(i) with stl vector带有 stl 向量的 foo[i] 和 foo->at(i) 之间的区别
【发布时间】:2010-01-13 22:49:36
【问题描述】:

有什么原因吗

foo = (bar->at(x))->at(y);

有效但

foo = bar[x][y];

不起作用,其中 bar 是向量的向量(使用 c++ stl)

声明是:

std::vector<:vector object> * >

【问题讨论】:

  • 向量是如何声明的,std::vector&lt;std::vector *&gt;?您对at 的使用暗示了指针,还是拼写错误?否则不应该是bar.at(x).at(y)吗?
  • 仅仅因为 C++ 有指针并不意味着程序中的每个变量都必须是一个。从中删除每个指针,它应该可以工作。
  • 看起来 bar 是一个指向包含指针的容器的指针。但如果有真正的“酒吧”类型会很高兴
  • 就像我和其他人在下面所说的那样,你不能在指针上使用operator[] 而不取消引用它们。 (bar-&gt;operator[]()(*bar)[]。免费函数可能是第二个最干净的方法。最干净的是没有指针。
  • @GMan:当然可以在指针上使用 []。它只是不符合 OP 的意图。 ;)

标签: c++ stl vector


【解决方案1】:

它是向量的向量还是向量的指针向量?您的代码应该按照宣传的方式工作

typedef std::vector<int> vec_int;
typedef std::vector<vec_int> multi_int;

multi_int m(10, vec_int(10));

m.at(2).at(2) = /* ... */;
m[2][1] = /* ... */;

但您的代码似乎有:

typedef std::vector<vec_int*> multi_int; // pointer!
multi_int* m; // more pointer!

如果你有指针,你需要先取消引用它们才能使用operator[]

(*(*m)[2])[2] = /* ... */;

那可能很难看。也许暂时使用引用:

multi_int& mr = m;
(*mr[2])[2] = /* ... */;

虽然还是有些难看。也许免费功能会有所帮助:

template <typename T>
typename T::value_type& access_ptr(T* pContainer,
                                    unsigned pInner, unsigned pOuter)
{
    return (*(*pContainer)[pInner])[pOuter]);
}

access_ptr(m, 2, 2) = /* ... */

最好是去掉指针。指针可能会泄漏并有各种各样的问题,例如在抛出异常时泄漏。如果您必须使用指针,请使用 boost 中的 pointer container 作为内部向量,并将实际对象存储在 smart pointer 中。

另外,你的标题有点误导。 atoperator[] 之间的区别在于 at 进行范围检查。否则,它们是相同的。

【讨论】:

  • 我假设barstd::vector&lt;std::vector&lt;T&gt; &gt;*,因此-&gt;at()
  • 应该是std::vector&lt;std::vector&lt;T&gt;* &gt;*,有两个-&gt;
  • 哎呀,我没看到另一个。查尔斯是对的​​,当然
【解决方案2】:

你确定你有向量的向量吗?如果你这样做了

foo = bar[x][y];

会像

foo = bar.at(x).at(y);

但没有at 的范围检查和异常行为。

如果bar-&gt;at(x)-&gt;at(y) 有效,那么这可能在某种程度上等同于(*(*bar)[x])[y] 而不是bar[x][y],但一定意味着bar 不是向量的向量。

【讨论】:

    【解决方案3】:

    好吧,如果 bar 是一个指针(如第一个示例所示),您需要将第二个示例重写为:

    (*(*foo)[x])[y]
    

    【讨论】:

      【解决方案4】:

      看起来你有一个指向向量的指针的指针...

      所以如果你想按照你已经尝试过的方式去做,你需要

      foo = (*((*bar)[x]))[Y];

      使用向量的向量(即 std::vector> 代替。

      编辑:另外值得注意的是 at 确实会进行一些范围检查,因此,如果您不需要这些范围检查,则比使用 operator[] 慢。

      【讨论】:

        【解决方案5】:

        如果 bar 是一个指针,你需要先取消引用它:

        (*bar)[x][y]
        

        如果它是一个指向向量指针向量的指针:

        (*(*bar)[x])[y]
        

        正如R Samuel Klatchko 和其他人提到的

        【讨论】:

          【解决方案6】:

          对于

          foo = (bar->at(x))->at(y);
          

          bar 必须是一个指针,并且它指向的向量必须包含指针。

          对于

          foo = bar[x][y];
          

          要工作,bar 必须是包含向量(不是指针)的vector(不是指针)。

          【讨论】:

            【解决方案7】:

            取决于您如何定义“有效”和“无效”。当它“不起作用”时会发生什么? 两者的主要区别在于at 执行边界检查,而operator[] 不执行。

            但在您的情况下,问题在于bar 不是向量的向量。它似乎是一个指向向量指针向量的 指针。 (这本身就是一个不好的迹象。它可能不需要是一个指针。所有东西也都是用new动态分配的吗?默认情况下不要这样做)

            这意味着您正在尝试在指针上调用operator[],而不是向量——它已定义,但执行的操作与您预期的不同。第二种情况下的代码实际上等同于(*(bar+x))[y] - 除了越界产生未定义的行为外,结果将是指向任何类型 foo 的向量的指针,而不是该向量的元素。

            【讨论】:

              猜你喜欢
              • 2022-11-30
              • 1970-01-01
              • 1970-01-01
              • 2016-12-01
              • 2016-09-09
              • 2017-07-04
              • 2012-07-26
              • 2017-03-14
              • 1970-01-01
              相关资源
              最近更新 更多