【发布时间】:2021-11-26 19:42:52
【问题描述】:
我正在使用可变参数模板来构造地图的键,将数字计算为基数:
template<typename T>
uint64_t key(int base, T n)
{
return uint64_t(n) % base;
}
template<typename T, typename... Args>
uint64_t key(int base, T n, Args... rest)
{
return key(base, rest...) * base + (uint64_t(n) % base);
}
用key(10, 1, 2, 3) 调用它会给我一个带有十进制值321 的键。我更希望获得123 作为密钥,并且我找到了一个可行的解决方案:
template<typename T>
uint64_t keyHelper(int& mul, int base, T n)
{
mul = base;
return uint64_t(n) % base;
}
template<typename T, typename... Args>
uint64_t keyHelper(int& mul, int base, T n, Args... rest)
{
int mul_tmp;
uint64_t result = keyHelper(mul_tmp, base, rest...) +
(uint64_t(n) % base) * mul_tmp;
mul = mul_tmp * base;
return result;
}
template<typename... Args>
uint64_t key(int base, Args... args)
{
int mul;
return keyHelper(mul, base, args...);
}
这个解决方案感觉像是一个 hack,因为它传递了一个引用来修复乘法的指数。是否有一种简单的可变方式让模板按所需顺序计算数字,即123?我已经看到了反转可变参数的解决方案,它们似乎过于复杂。
【问题讨论】:
-
在标准 C++ 中没有简单的方法来反转参数的顺序。您可能会在库中找到一些助手,也许 Boost::Hana 有一些。在您的情况下,我建议将
a * p^2 + b * p + c重写为(a * p + b) * p + c,这样您就不需要颠倒参数的顺序。 -
也许有一些简单的方法可以滥用
std::tuple或其他容器,但我没有找到解决方案:/ -
只要有一个元组,它就会和你的一样hacky ;)
-
@hochl 你可以先
make_tuple或者forward_as_tuple然后std::apply,但是你还是要反过来std::tuple,没有简单的办法。 -
您可以尝试使用
sizeof...(Args)预先计算给定迭代的基数。
标签: c++ templates variadic-templates