最通用的方式(不一定是最有效的方式)是:
c.insert( c.end(), value );
当然,其中value
需要适合容器c
(您可以使用decltype(c)::value_type
)。在关联容器的情况下,例如map
,它是std::pair
.
这适用于除std::forward_list
. 对于某些容器,元素会在最后添加,对于某些容器,这c.end()
只是一个可能被忽略的提示。
作为评论的后续,这里是高级的东西;)
当您想将已知数量的元素插入给定容器c
(类型为C
)并且希望至少有点效率时,您应该检测容器类型是否支持reserve()
并在插入元素之前调用它。
以下方法检测reserve()
正确(链接说明如何):
template< typename C, typename = void >
struct has_reserve
: std::false_type
{};
template< typename C >
struct has_reserve< C, std::enable_if_t<
std::is_same<
decltype( std::declval<C>().reserve( std::declval<typename C::size_type>() ) ),
void
>::value
> >
: std::true_type
{};
现在您可以使用它std::enable_if_t
来选择性地保留空间。一个示例可能如下所示:
template< typename C >
std::enable_if_t< !has_reserve< C >::value >
optional_reserve( C&, std::size_t ) {}
template< typename C >
std::enable_if_t< has_reserve< C >::value >
optional_reserve( C& c, std::size_t n )
{
c.reserve( c.size() + n );
}
template< typename C, typename T, std::size_t N >
void add_array( C& c, const std::array< T, N >& a )
{
optional_reserve( c, N );
for( const auto& e : a ) {
c.insert( c.end(), typename C::value_type( e ) ); // see remark below
}
}
add_array
现在可以使用所有标准容器(除了)调用它,std::forward_list
它将调用无序关联容器。reserve()
std::vector
由于上述方法不需要对特定容器类型进行显式特化或重载,因此它也适用于非标准容器,只要它们的接口设计合理地类似于标准容器的接口即可。(事实上我过去有几个这样的“自制”容器和上面的 Just-Works™)
A remark about the conversion in the above code: The reason for converting the T
s to C::value_type
is just to show that this would be the correct place if it is needed. In the above example it might look superfluous, but in my real-world code I call a special conversion traits class to convert the e
s (which are encoded strings) into the correct value type for any container.