使用具有非 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);

See it live on Wandbox