为何C++序列容器有assign方法而关联容器没有?
C++容器
assign方法的设计疑问 C++的四种基础序列容器(vector、forward_list、list、deque)都提供了assign方法。以std::vector为例,它的assign方法包含以下重载:
void assign( size_type count, const T& value ); template< class InputIt > void assign( InputIt first, InputIt last ); void assign( std::initializer_list<T> ilist );
从语义上看,assign的作用似乎和临时对象赋值(operator=)等价,比如vec.assign({1,2,3});和vec = {1,2,3};效果相近,那为什么要单独提供assign方法?
同时,std::map这类关联容器却没有assign方法,这又是为什么?是什么原因让序列容器必须具备该方法,而关联容器不需要?我最初猜测序列容器的assign能避免临时对象创建,但这个逻辑似乎也适用于关联容器(而且移动赋值下临时对象的开销几乎可以忽略)。
这个问题有实际应用价值——我正在设计一款兼具序列容器与关联容器特性的自定义容器,需要判断是否有必要为它提供assign方法。
有人觉得这个问题属于“基于观点的问题”,不适合提问,但我并不认同。这个问题不是询问读者的语言设计选择,而是要找出C++语言设计者做出该决策的根本依据,存在客观正确答案:这个决策是由特定人员基于特定理由制定的,我想探寻这些理由。
可以通过以下几种基于事实的方式解答这类问题:
- 存在清晰且有说服力的技术依据,让几乎所有合格设计者都会做出相同选择。这种情况下只需证明序列容器使用
assign有显著性能优势,而关联容器没有,这些性能特性并非主观观点。 - 存在同期的依据文档。我暂时没找到针对这个特定问题的文档,但不代表它不存在。任何此类文档都能明确回答该问题,进一步证明本问题有客观正确答案,只是可能难以发掘。
- 同理,参与或见证该决策的人员可基于自身经验提供答案。此时可能会质疑答案的可信度,但这并不使其成为主观观点。
- 和多数语言特性一样,可能存在标准化前的提案及相关修订历史,从中至少能推断出可能的动机。基于此类提案的合理推测并非主观观点,尽管推测包含一定主观判断成分。
内容的提问来源于Stack Exchange,提问作者Scott McPeak
相关产品推荐
相关产品推荐

