最generic way(不一定是最有效的方式)是:
c.insert(c.end(), value);
其中,當然,value
需要適合於容器c
(您可以使用decltype(c)::value_type
)。在關聯容器的情況下,例如map
,這是一個std::pair
。
這適用於全部標準容器除了std::forward_list
。對於某些容器,元素隨後會添加到最後,因爲某些c.end()
只是一個可能被忽略的提示。
作爲後續行動的意見,這裏的先進的東西;)
當你要插入已知數量的元素到給定容器c
(的C
型),你想至少要稍微有效一些,你應該檢測容器類型是否支持reserve()
並在插入元素之前調用它。
下面的方法detects reserve()
correctly(鏈接解釋如何):
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™)
關於上述代碼轉換的評論:將T
s轉換爲C::value_type
的原因是表明如果需要的話,這將是正確的地方。在上面的例子中,它可能看起來多餘,但在我的真實世界的代碼中,我調用一個特殊的轉換特徵類來將e
(這是編碼的字符串)轉換爲任何容器的正確值類型。
爲什麼不使用'push_back'而不是'emplace'? 'push_back'由兩者支持,似乎更好地匹配你正在嘗試做的事情。 –
'push_back'不受類似'std :: list'的支持。我想這可能是一個有效的妥協。 – thirtythreeforty
'push_back'由'std :: list'支持:http://www.cplusplus.com/reference/list/list/push_back/ –