如何扩展元组以匹配提供的参数?
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)...}};
}
我有一个函数(在简化逻辑后)采用以下形式
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)...);
}
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)...}};
}