 user1998012 - 2 years ago 108
C++ Question

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

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++? Xirema

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;
}
``````
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download