我正在使用可變引數模板來構造映射的鍵,計算基數的數字:
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...);
}
這個解決方案感覺就像一個黑客,因為它傳遞了一個參考來修復乘法的指數。是否有一種簡單的可變方式,模板按所需順序計算數字,即123?我已經看到了反轉可變引數的解決方案,它們似乎過于復雜。
uj5u.com熱心網友回復:
從 C 17 開始,我會使用折疊運算式(op,...)來做到這一點:
template<class B, class ... Args>
auto key(B base, Args ... args) {
std::common_type_t<Args...> res{};
( (res *= base, res = args % base), ... );
return res;
}
演示
uj5u.com熱心網友回復:
這個怎么樣:
template<typename T>
uint64_t key_impl(int base, unsigned int exp, T n)
{
return uint64_t(n) % base;
}
template<typename T, typename... Args>
uint64_t key_impl(int base, unsigned int exp, T n, Args... rest)
{
uint64_t res = uint64_t(n) % base;
for (unsigned int i = 0u; i < exp; i)
res *= base;
return key_impl(base, exp - 1u, rest...) res;
}
template<typename... Args>
uint64_t key(int base, Args... args)
{
return key_impl(base, sizeof...(Args) - 1u, args...);
}
uj5u.com熱心網友回復:
由于引數的數量是已知的,最大指數是已知的,你可以用它來計算總和
template<typename T, typename... Args>
uint64_t key(int base, T n, Args... rest)
{
return (uint64_t(n) % base) * std::pow(base, sizeof...(rest))
key(base, rest...);
}
(基本情況不變)
演示
請注意,您實際上不應該std::pow在這里使用;寫一個函式來代替整數取冪。
uj5u.com熱心網友回復:
根據@Andrey Semashev 的評論,我找到了一個感覺更好的解決方案:
template<int n>
uint64_t exp(int base)
{
return base * exp<n - 1>(base);
}
template<>
uint64_t exp<0>(int base)
{
return 1;
}
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...)
(uint64_t(n) % base) * exp< sizeof...(rest) >(base);
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/312606.html
下一篇:模板函式的雙模板引數
