如何扩展元组以匹配提供的参数?

How to expand Tuple to Match Arguments Provided?

我有一个函数(在简化逻辑后)采用以下形式

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));
}

我想将此函数模板化,以便它可以处理与用户传入的一样多或一样少的数据集。

auto [serif, sansserif, monospace] = get_font_heaps(serif_data, sansserif_data, monospace_data);
auto [comic_sans] = get_font_heaps(comic_sans_data);

我开始尝试像这样重写逻辑:

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)...);
}

但显然,即使编译成功,它也不会完全做我想做的事:它从这段代码中创建了一个嵌套的元组,形式为std::tuple<font_heap, std::tuple<font_heap, std::tuple<font_heap>>>,而我想要的是std::tuple<font_heap, font_heap, font_heap>

如何重写此逻辑以实现我的意图?我使用的是 MSVC 2017.3,所以我可以使用很多 C++17 功能,但不能使用折叠表达式(我怀疑这会大大简化逻辑)。

看来你只是想要

template <class... Data>
auto get_font_heaps(Data const&... d) {
    return std::make_tuple(get_font_heap_from_data(d)...);
}

那是 C++14。我们甚至可以使它成为 C++11,并使用一个别名来丢弃它的输入:

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)...);
}

在评论中提出了一个很好的观点。由于我们所有的类型都是相同的,所以我们应该 return a std::array 而不是 std::tuple:

template <class... Data>
std::array<font_heap, sizeof...(Data)>
get_font_heaps(Data const&... d) {
    return {{get_font_heap_from_data(d)...}};
}