使用具有非 constexpr 值的 int 模板函数
Use int-templated function with non-constexpr values
我有一些功能
template<int N>
auto foo();
我想用编译时未知的模板参数调用这个函数,但它们只能是数字 1 到 c
(其中 c
是一个固定常数,例如 10)。对于这个问题,有没有比以下更好的通用解决方案?
auto foo(int n)
{
switch(n) {
case 1:
return foo<1>();
case 2:
return foo<2>();
...
case 10:
return foo<10>();
}
}
如果函数要用于更大的整数集,这个解决方案会变得非常冗长。
这个模板参数是必需的,因为该函数使用 class 和这样一个模板参数,其中它用于静态大小数组的大小。但这不应该与问题真正相关。我无法更改模板版本。
如果可以调用加法辅助函数,那么使用整数序列(来自 std::make_integer_sequence<MAX>{}
,其中 MAX-1
是整数值的最大值)结合模板折叠、三元运算符怎么样和逗号运算符?
我的意思是……下面呢?
#include <iostream>
#include <utility>
template <int N>
void foo ()
{ std::cout << N << '\n'; }
template <int ... Is>
void foo (int n, std::integer_sequence<int, Is...>)
{ ((n == Is ? (foo<Is>(), 0) : 0), ...); }
void foo (int n)
{ foo(n, std::make_integer_sequence<int, 42>{}); }
int main()
{
foo(2); // print 2
foo(3); // print 3
foo(5); // print 5
foo(7); // print 7
}
如果你可以使用 C++20(所以模板 lambdas)你可以避免额外的(外部)函数并且你的 foo()
可以简单地写成
void foo (int n)
{
[&]<int ... Is>(std::integer_sequence<int, Is...>)
{ ((n == Is ? (foo<Is>(), 0) : 0), ...); }
(std::make_integer_sequence<int, 42>{});
}
当然可以:
template <int... Ns>
decltype(auto) dispatch_foo(int const n, std::integer_sequence<int, Ns...>) {
static constexpr void (*_foos[])() { &foo<Ns>... };
return _foos[n]();
}
template <int Nmax>
decltype(auto) dispatch_foo(int const n) {
return dispatch_foo(n, std::make_integer_sequence<int, Nmax>{});
}
用法:
dispatch_foo<c>(n);
我有一些功能
template<int N>
auto foo();
我想用编译时未知的模板参数调用这个函数,但它们只能是数字 1 到 c
(其中 c
是一个固定常数,例如 10)。对于这个问题,有没有比以下更好的通用解决方案?
auto foo(int n)
{
switch(n) {
case 1:
return foo<1>();
case 2:
return foo<2>();
...
case 10:
return foo<10>();
}
}
如果函数要用于更大的整数集,这个解决方案会变得非常冗长。
这个模板参数是必需的,因为该函数使用 class 和这样一个模板参数,其中它用于静态大小数组的大小。但这不应该与问题真正相关。我无法更改模板版本。
如果可以调用加法辅助函数,那么使用整数序列(来自 std::make_integer_sequence<MAX>{}
,其中 MAX-1
是整数值的最大值)结合模板折叠、三元运算符怎么样和逗号运算符?
我的意思是……下面呢?
#include <iostream>
#include <utility>
template <int N>
void foo ()
{ std::cout << N << '\n'; }
template <int ... Is>
void foo (int n, std::integer_sequence<int, Is...>)
{ ((n == Is ? (foo<Is>(), 0) : 0), ...); }
void foo (int n)
{ foo(n, std::make_integer_sequence<int, 42>{}); }
int main()
{
foo(2); // print 2
foo(3); // print 3
foo(5); // print 5
foo(7); // print 7
}
如果你可以使用 C++20(所以模板 lambdas)你可以避免额外的(外部)函数并且你的 foo()
可以简单地写成
void foo (int n)
{
[&]<int ... Is>(std::integer_sequence<int, Is...>)
{ ((n == Is ? (foo<Is>(), 0) : 0), ...); }
(std::make_integer_sequence<int, 42>{});
}
当然可以:
template <int... Ns>
decltype(auto) dispatch_foo(int const n, std::integer_sequence<int, Ns...>) {
static constexpr void (*_foos[])() { &foo<Ns>... };
return _foos[n]();
}
template <int Nmax>
decltype(auto) dispatch_foo(int const n) {
return dispatch_foo(n, std::make_integer_sequence<int, Nmax>{});
}
用法:
dispatch_foo<c>(n);