模板类vector
中的许多方法都对value_type
个对象进行const引用,例如:
void push_back (const value_type& val);
resize
按value_type
参数取值:
void resize (size_type n, value_type val = value_type());
作为一个非专业的C ++程序员,我只能想到这个选择的缺点(例如,如果size_of(value_type)
足够大,可能会发生堆栈溢出)。因此,我想对那些对语言有更多见解的人提出这样的要求:
此选择背后的设计理由是什么?
答案 0 :(得分:9)
void resize( size_type count, T value = T() );
此功能已从C ++ 11 删除。
C ++ 11有resize()
void resize( size_type count );
void resize( size_type count, const value_type& value);
:
value_type
这很容易理解。第一个使用{{1}}类型的默认构造对象在调整大小时填充向量,第二个使用在调整大小时从中复制的值。
答案 1 :(得分:6)
这似乎是一个设计缺陷,现在已经修复了。
C ++ 98标准指定容器中的一个成员函数通过值而不是const引用传递其参数(T):
void resize(size_type sz,T c = T());
这一事实多年来一直在讨论/辩论,这是第一次在批准C ++ 98之前。按值传递此参数的基本原理是:
这样可以保证自引用语句有效,例如:
v.resize(v.size() + 1, v[0]);
然而,这个理由并不令人信服,因为push_back的签名是:
void push_back(const T& x);
push_back具有类似的语义来调整大小(追加)。并且push_back也必须在自引用案例中起作用:
v.push_back(v[0]); // must work
通过值传递T的问题在于它比通过引用传递要贵得多。反过来也是如此,但是当它成立时它通常远不那么戏剧性(例如对于标量类型)。
即使可以使用移动语义,按值传递此参数也很昂贵。考虑例如vector>:
std::vector<int> x(1000); std::vector<std::vector<int>> v; ... v.resize(v.size()+1, x);
在按值传递的情况下,x被复制一次到resize的参数。然后在内部,因为代码在编译时无法知道向量增加了多少调整大小,x通常会第二次从resize参数复制(不移动)到向量中的适当位置。
使用pass-by-const-reference,上例中的x只需复制一次。在这种情况下,x具有昂贵的复制构造函数,因此任何可以保存的副本都可以节省大量成本。
如果我们对push_back有效,那么我们也应该有效调整大小。采用参考参数的resize已经编码并在CodeWarrior库中发布,没有我所知道的问题报告。
提议的决议:
更改23.3.3 [deque],p2:
class deque { ... void resize(size_type sz, const T& c);
更改23.3.3.3 [deque.capacity],p3:
void resize(size_type sz, const T& c);
更改23.3.5 [list],p2:
class list { ... void resize(size_type sz, const T& c);
更改23.3.5.3 [list.capacity],第3页:
void resize(size_type sz, const T& c);
更改23.3.6 [vector],p2:
class vector { ... void resize(size_type sz, const T& c);
更改23.3.6.3 [vector.capacity],第11页:
void resize(size_type sz, const T& c);