为什么
foo = (bar->at(x))->at(y);
可以运行,但是
foo = bar[x][y];
无法运行,其中bar是一个向量的向量(使用c++ stl)
声明如下:
注:Object为一个对象类型。std::vector< std::vector < Object * > * >
它是一个向量的向量还是指向向量的指针的向量?你的代码应该像广告中所说的那样工作:
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中。at
和operator[]
之间的区别在于at
执行范围检查。否则,它们是相同的。bar
是一个std::vector<std::vector<T> >*
,因此使用了->at()
。 - jalfstd::vector<std::vector<T>* >*
,有两个->
。 - CB Bailey你确定你有一个向量的向量吗?如果是这样的话,那么
foo = bar[x][y];
would be like
foo = bar.at(x).at(y);
但不具备at
的范围检查和异常行为。
如果bar->at(x)->at(y)
可行,则可能与(*(*bar)[x])[y]
有些相似,而不是bar[x][y]
,但这必须意味着bar
不是向量的向量。
好的,如果bar是一个指针(正如第一个例子所示),那么你需要重写你的第二个例子:
(*(*foo)[x])[y]
看起来你有一个指向指针向量的指针...
所以如果你想尝试这样做,你需要
foo = (*((*bar)[x]))[Y];
使用向量的向量(即std::vector< std::vector< datatype > >)。
编辑:还值得注意的是,at确实进行一些范围检查,因此,只要您不需要这些范围检查,就比使用operator[]慢。
对于
foo = (bar->at(x))->at(y);
要让bar
工作,它必须是一个指针,并且它所指向的向量必须包含指针。
对于
foo = bar[x][y];
要使其工作,bar
必须是一个包含向量(而不是指针)的 vector
。
取决于你如何定义“工作”和“不工作”。当它“不工作”时会发生什么?
两者之间的主要区别在于at
执行边界检查,而operator[]
则不执行。
但在你的情况下,问题在于bar
不是一个向量的向量。它似乎是指向指针的向量的指针。(这本身就是一个坏迹象。它可能不需要是一个指针。一切也都是用new
动态分配的吗?默认情况下不要这样做)
这意味着你试图在指针上调用operator[]
,而不是一个向量——虽然它被定义了,但它做的事情与你期望的不同。你第二个例子中的代码实际上等价于(*(bar+x))[y]
——除了越界导致未定义行为外,结果将是一个指向foo类型的向量的指针,而不是该向量的一个元素。
std::vector<std::vector *>
这个向量是怎么声明的?你使用at
表示使用指针,或者这是一个打字错误吗?否则,应该写成bar.at(x).at(y)
才对。 - Skurmedeloperator[]
。(可以使用bar->operator[]()
或(*bar)[]
。自由函数可能是第二干净的方法。最干净的方法是不使用指针。) - GManNickG