返回与C 中Variadic模板相对应的元组
Return a tuple corresponding to variadic template in C++17
如何从获取variadic模板列表的函数中返回元组?元组类型应与参数类型相同。
template <typename ... T, typename D>
std::tuple<T...> foo(D&& Duration) {
// How to do this?
if constexpr(sizeof... (args) > 0) {
...
}
// What to return?
}
这个想法是使用C 17结构绑定,以便我可以做类似的事情:
auto var = std::chrono::seconds(19874);
auto [h, m] = foo<std::chrono::hours, std::chrono::minutes> (var);
auto [m, s, ms] = foo<std::chrono::minutes, std::chrono::seconds, std::chrono::milliseconds>(var);
在两种情况下,总和(H:M或M:S:MS)应为19874秒。
此代码应执行您的要求。它使用每种Ouptut类型的chrono_extract
的调用列表来构建元组。初始化列表参数是按照标准处理的顺序处理的,因此,即使使用逗号的使用可能看起来像是这样,这也不应该对任何重新排序敏感。chrono_extract
函数将输入持续时间投入到输出持续时间的类型上,然后从输入中减去输出(通过参考传递,因此其值将反映在chrono_components
中)。为了正确运行该算法,我们需要在列表中找到最小的时间组件,并以最小的分辨率运行所有计算(否则会有持续时间施放错误)。还提供了一个主张,以确保返回持续时间类型的顺序减小,因为如果函数以不同的顺序为单位,则该函数将无法正常运行。可以添加的一种可能的增强功能是,如果分解中剩下任何东西(如下代码中的第一个测试案例中,在元组中返回元组中的"剩余"(与输入类型相同)。
#include <chrono>
#include <iostream>
#include <tuple>
#include <type_traits>
template <typename lhs_t, typename rhs_t, typename... other_ts>
constexpr void assert_decreasing_ratios() {
static_assert(std::ratio_greater_v<typename lhs_t::period,
typename rhs_t::period>,
"Periods are non-decreasing.");
if constexpr (sizeof...(other_ts)) {
assert_decreasing_ratios<rhs_t, other_ts...>();
}
}
template <typename return_duration_t, typename input_duration_t>
return_duration_t chrono_extract(input_duration_t& value) {
auto extracted = std::chrono::duration_cast<return_duration_t>(value);
value -= extracted;
return extracted;
}
template <typename... return_ts, typename duration_t>
std::tuple<return_ts...> chrono_components(duration_t value) {
assert_decreasing_ratios<return_ts...>();
using smallest_t = std::tuple_element_t<sizeof...(return_ts) - 1,
std::tuple<return_ts...>>;
auto small_value = std::chrono::duration_cast<smallest_t>(value);
return {chrono_extract<return_ts>(small_value)...};
}
int main()
{
std::chrono::seconds before(19874);
{
auto [h, m] = chrono_components<std::chrono::hours,
std::chrono::minutes>(before);
std::chrono::seconds after(h + m);
std::cout << h.count() << " hours "
<< m.count() << " minutes = "
<< after.count() << " secondsn";
}
{
auto [m, s, ms] = chrono_components<std::chrono::minutes,
std::chrono::seconds,
std::chrono::milliseconds>(before);
auto after =
std::chrono::duration_cast<std::chrono::seconds>(m + s + ms);
std::cout << m.count() << " minutes "
<< s.count() << " seconds "
<< ms.count() << " milliseconds = "
<< after.count() << " secondsn";
}
}
输出
5 hours 31 minutes = 19860 seconds
331 minutes 14 seconds 0 milliseconds = 19874 seconds
第一行显示秒值已被截断,因为它不是确切的分钟数。
相关文章:
- C++:TypeDef使用元组
- Pybind11:将元组列表从Python传递到C++
- 重载元组索引运算符-C++
- 在C++中,如何通过几种类型从元组中选择多个元素
- 将fold表达式与std::一起用于两个元组
- std::ranges::elements_view,用于自定义类似元组的数据
- 将元组的向量转换/构造为堆
- 专用于 std 元组的模板,而无需用户执行remove_cvref
- 将元组的向量构造成堆
- 元组由 Swig 生成的 Python 包装器返回,用于C++向量
- 将元组类型扩展为可变参数模板?
- 时间复杂度 当具有复合数据类型(如元组或对)时?
- 类内部和外部静态 constexpr 元组之间的差异
- 可变参数模板与使用元组在参数中添加不同的数据对
- 访问和打印元组中的数据,并使用 C++14 使用模板函数显示数据
- boost::包含提升单元的元组的哈希值
- 我正在寻找一种优雅的方式来从元组向量创建tuple_element向量
- 如何在可变参数模板函数中遍历可变参数元组?
- 如何使用 SML 随机生成八进制元组
- 返回与C 中Variadic模板相对应的元组