user1998012 - 1 year ago 98

C++ Question

The "hello, world" of template meta-programming can be considered the factorial code:

`template <unsigned int n>`

struct factorial {

enum { value = n * factorial<n - 1>::value };

};

template <>

struct factorial<0> {

enum { value = 1 };

};

So we can get the factorial by doing

`cout << factorial<4>::value << endl; //It will print 24`

But if I do:

`int N = 4;`

cout << factorial<N>::value << endl; //COMPILE ERROR

Is there a way to give dynamically values to to a templated function in C++?

Recommended for you: Get network issues from **WhatsUp Gold**. **Not end users.**

Answer Source

This might work for you.

```
#include<iostream>
#include<array>
#include<utility>
//Only >=c++14 supports doubles in constexpr, so we're sticking to integers.
template<unsigned int I>
struct FAC {
static constexpr uint64_t val = I * FAC<I-1>::val;
};
template<>
struct FAC<0> {
static constexpr uint64_t val = 0;
};
template<>
struct FAC<1> {
static constexpr uint64_t val = 1;
};
template<size_t ... I>
uint64_t factorial_impl(std::index_sequence<I...>, const unsigned int i) {
constexpr std::array<uint64_t, sizeof...(I)> a = {FAC<I>::val...};
return a[i];
}
uint64_t factorial(const unsigned int i) {
return factorial_impl(std::make_index_sequence<22>(), i); //Can't store factorial values above index 22 without using floating-point values
}
int main() {
std::cout << "Which factorial do you want? [1-22]: ";
unsigned int index = 0;
std::cin >> index;
std::cout << "Value of " << index << " is " << factorial(index) << std::endl;
return 0;
}
```

If you'd rather it work with doubles, you'll need a c++14-compliant compiler, but this slight modification should work:

```
#include <iostream>
#include<array>
#include<utility>
template<unsigned int I>
struct FAC {
static constexpr double val = I * FAC<I-1>::val;
};
template<>
struct FAC<0> {
static constexpr double val = 0;
};
template<>
struct FAC<1> {
static constexpr double val = 1;
};
template<size_t ... I>
double factorial_impl(std::index_sequence<I...>, const unsigned int i) {
constexpr std::array<double, sizeof...(I)> a = {FAC<I>::val...};
return a[i];
}
double factorial(const unsigned int i) {
return factorial_impl(std::make_index_sequence<170>(), i); //Values above 170 are infinite.
}
int main() {
std::cout << "Which factorial do you want? [1-170]: ";
unsigned int index = 0;
std::cin >> index;
std::cout << "Value of " << index << " is " << factorial(index) << std::endl;
return 0;
}
```