Reputation: 20396
I have a function that (after simplifying the logic) takes the form
std::tuple<font_heap, font_heap> get_font_heaps(std::vector<uint8_t> const& a, std::vector<uint8_t> const& b) {
return std::make_tuple(get_font_heap_from_data(a), get_font_heap_from_data(b));
}
I'd like to templatize this function so that it can handle as many or as few datasets as the user passes in.
auto [serif, sansserif, monospace] = get_font_heaps(serif_data, sansserif_data, monospace_data);
auto [comic_sans] = get_font_heaps(comic_sans_data);
I've started by trying to rewrite the logic like so:
template<typename ... FontDatas>
auto get_font_heaps(std::vector<uint8_t> const& data, FontData&& ...datas) {
if constexpr(sizeof...(FontDatas) == 0) {
return std::make_tuple(get_font_heap_from_data(data));
else {
return std::make_tuple(get_font_heap_from_data(data), get_font_heaps(std::forward<FontDatas>(datas)...);
}
But obviously, even if this compiles, it doesn't quite do what I want: it creates a nested tuple out of this code, in the form std::tuple<font_heap, std::tuple<font_heap, std::tuple<font_heap>>>
, whereas what I want is std::tuple<font_heap, font_heap, font_heap>
How can I rewrite this logic to do what I intend? I'm using MSVC 2017.3, so I have access to a lot of C++17 features, but not Fold Expressions (which I suspect would simplify the logic greatly).
Upvotes: 2
Views: 164
Reputation: 303047
Seems like you just want
template <class... Data>
auto get_font_heaps(Data const&... d) {
return std::make_tuple(get_font_heap_from_data(d)...);
}
That's C++14. We could even make it C++11 with an alias that discards its input:
template <class T>
using font_heap_t = font_heap;
template <class... Data>
std::tuple<font_heap_t<Data>...>
get_font_heaps(Data const&... d) {
return std::make_tuple(get_font_heap_from_data(d)...);
}
T.C. makes a good point in the comments. Since all our types are the same, we should return a std::array
instead of a std::tuple
:
template <class... Data>
std::array<font_heap, sizeof...(Data)>
get_font_heaps(Data const&... d) {
return {{get_font_heap_from_data(d)...}};
}
Upvotes: 5