通過引入std::apply()
,這是非常簡單的:
template <class Tuple,
class T = std::decay_t<std::tuple_element_t<0, std::decay_t<Tuple>>>>
std::vector<T> to_vector(Tuple&& tuple)
{
return std::apply([](auto&&... elems){
return std::vector<T>{std::forward<decltype(elems)>(elems)...};
}, std::forward<Tuple>(tuple));
}
std::apply()
是一個C++ 17的功能,但在C +可實現+14(請參閱可能的實施鏈接)。作爲一種改進,您可以添加SFINAE或static_assert
,Tuple中的所有類型實際上都是T
。
T.C.作爲分出來,這招致每一元件的額外拷貝,因爲std::initializer_list
由const
陣列的支持。那真不幸。我們贏得了一些不必對每個元素進行邊界檢查,但在複製上失去一些。複製結束是太貴了,一個替代的實現是:
template <class Tuple,
class T = std::decay_t<std::tuple_element_t<0, std::decay_t<Tuple>>>>
std::vector<T> to_vector(Tuple&& tuple)
{
return std::apply([](auto&&... elems) {
using expander = int[];
std::vector<T> result;
result.reserve(sizeof...(elems));
expander{(void(
result.push_back(std::forward<decltype(elems)>(elems))
), 0)...};
return result;
}, std::forward<Tuple>(tuple));
}
的擴張招的說明,請參見this answer。請注意,由於我們知道該包不是空的,因此我放棄了領先的0
。用C++ 17,這變得與摺疊表達清潔器:
return std::apply([](auto&&... elems) {
std::vector<T> result;
result.reserve(sizeof...(elems));
(result.push_back(std::forward<decltype(elems)>(elems)), ...);
return result;
}, std::forward<Tuple>(tuple));
雖然仍相對不一樣好的initializer_list
構造函數。不幸的。
[迭代過元組]的可能的複製(http://stackoverflow.com/questions/1198260/iterate-over-tuple) – filmor
完全不同。更好地與[索引技巧](http://loungecpp.wikidot.com/tips-and-tricks:indices)接觸。 – Xeo