I\'m testing out user defined literals. I want to make _fac
return the factorial of the number.
Having it call a constexpr
function works,
This is how I ended up doing it:
template <typename t>
constexpr t pow(t base, int exp) {
return (exp > 0) ? base * pow(base, exp-1) : 1;
};
template <char...> struct literal;
template <> struct literal<> {
static const unsigned int to_int = 0;
};
template <char c, char ...cv> struct literal<c, cv...> {
static const unsigned int to_int = (c - '0') * pow(10, sizeof...(cv)) + literal<cv...>::to_int;
};
template <int N> struct factorial {
static const unsigned int value = N * factorial<N - 1>::value;
};
template <> struct factorial<0> {
static const unsigned int value = 1;
};
template <char ...cv>
constexpr unsigned int operator "" _fac()
{
return factorial<literal<cv...>::to_int>::value;
}
Huge thanks to KerrekSB!
I may be wrong, but I think constexpr functions can also be called with non-constant arguments (in which case they don't give a constant expression and are evaluated at runtime). Which wouldn't work well with non-type template arguments.
@Pubby. The easy way to digest the char non-type parameter pack is to cature it into an initializer list for a string. Then you can use atoi, atof, etc:
#include <iostream>
template<char... Chars>
int
operator "" _suffix()
{
const char str[]{Chars..., '\0'};
return atoi(str);
}
int
main()
{
std::cout << 12345_suffix << std::endl;
}
Remember to tack on a null character for the C-style functions.
In order to make use of constexpr with user defined literals, you apparently have to use a variadic template. Take a look at the second listing in the wikipedia article for an example.
I don't know if there's a better way in C++11 to do this than the current accepted answer, but with relaxed constexpr
in C++14, you can just write "normal" code:
constexpr unsigned long long int operator "" _fac(unsigned long long int x) {
unsigned long long int result = 1;
for (; x >= 2; --x) {
result *= x;
}
return result;
}
static_assert(5_fac == 120, "!");