float or double in templated code - c++

The following example might seem nonsensical, but it's part of a larger high-performance code where the presented technique makes sense. I mention this just in case someone should suspect an XY question - it's most probably not.
I have a function with templated/compile-time operand:
template <int M>
int mul(int x){
return M * x;
}
Now I want to do the same for double, what is - of course - not allowed:
template <double M> // you can't do that!
int mul(double x){
return M * x;
}
So to still put in the double at compile time, I only see the following solution:
// create my constants
struct SevenPointFive{
static constexpr double VAL = 7.5;
}
struct ThreePointOne{
static constexpr double VAL = 3.1;
}
// modified function
template <class M>
int mul(double x){
return M::VAL * x;
}
// call it
double a = mul<SevenPointFive>(3.2);
double b = mul<ThreePointOne>(a);
Is there a better solution for the problem to somehow pass a double constant in a template parameter, without creating a struct for each value?
(I'm interested in a solution which actually uses double/float, not a hack with using two ints to create a rational number or fixed point ideas such as y = 0.01 * M * x.)

In C++11, it is not necessary to use templates at all. Simply use constexpr (generalised constant expressions) in a different way than you are.
#include <iostream>
constexpr double mul(double x, double y)
{
return x*y;
}
int main()
{
std::cout << mul(2.3, 3.4) << '\n';
double x;
std::cin >> x; // to demonstrate constexpr works with variables
std::cout << mul(2.3, x) << '\n';
}
Although I say templates aren't necessary (which they aren't in the example given) these can be templated if needed
template <class T> constexpr T mul(T x, T y) {return x*y;}
or (if you want to use the function for types that are better passed by const reference)
template <class T> constexpr T mul(const T &x, const T &y) {return x*y;}

You can conveniently pass floating point values in template parameters using user-defined literals.
Just write a literal that creates your envelope class. Then you can write something like
mul<decltype(3.7_c)>(7)
Or even better, have your function take the argument by value so you can write
mul(3.7_c, 7)
the compiler will make that just as efficient.
Below's an example of code that does this:
#include <iostream>
template <int Value, char...>
struct ParseNumeratorImpl {
static constexpr int value = Value;
};
template <int Value, char First, char... Rest>
struct ParseNumeratorImpl<Value, First, Rest...> {
static constexpr int value =
(First == '.')
? ParseNumeratorImpl<Value, Rest...>::value
: ParseNumeratorImpl<10 * Value + (First - '0'), Rest...>::value;
};
template <char... Chars>
struct ParseNumerator {
static constexpr int value = ParseNumeratorImpl<0, Chars...>::value;
};
template <int Value, bool, char...>
struct ParseDenominatorImpl {
static constexpr int value = Value;
};
template <int Value, bool RightOfDecimalPoint, char First, char... Rest>
struct ParseDenominatorImpl<Value, RightOfDecimalPoint, First, Rest...> {
static constexpr int value =
(First == '.' && sizeof...(Rest) > 0)
? ParseDenominatorImpl<1, true, Rest...>::value
: RightOfDecimalPoint
? ParseDenominatorImpl<Value * 10, true, Rest...>::value
: ParseDenominatorImpl<1, false, Rest...>::value;
};
template <char... Chars>
using ParseDenominator = ParseDenominatorImpl<1, false, Chars...>;
template <int Num, int Denom>
struct FloatingPointNumber {
static constexpr float float_value =
static_cast<float>(Num) / static_cast<float>(Denom);
static constexpr double double_value =
static_cast<double>(Num) / static_cast<double>(Denom);
constexpr operator double() { return double_value; }
};
template <int Num, int Denom>
FloatingPointNumber<-Num, Denom> operator-(FloatingPointNumber<Num, Denom>) {
return {};
}
template <char... Chars>
constexpr auto operator"" _c() {
return FloatingPointNumber<ParseNumerator<Chars...>::value,
ParseDenominator<Chars...>::value>{};
}
template <class Val>
int mul(double x) {
return Val::double_value * x;
}
template <class Val>
int mul(Val v, double x) {
return v * x;
}
int main() {
std::cout << mul<decltype(3.79_c)>(77) << "\n";
std::cout << mul(3.79_c, 77) << "\n";
return 0;
}

constexpr double make_double( int64_t v, int64_t man );
write a function that makes a double from a base and mantissa. This can represent every non-special double.
Then write:
template<int64_t v, int64_t man>
struct double_constant;
using the above make_double and various constexpr access methods.
You can even write base and exponent extracting constexpr functions I suspect. Add a macro to remove DRY, or use a variable.
Another approach is:
const double pi=3.14;//...
template<double const* v>
struct dval{
operator double()const{return *v;}
};
template<class X>
double mul(double d){
return d*X{};
}
double(*f)(double)=mul<dval<&pi>>;
which requires a variable to point to, but is less obtuse.

If you don't want to create type envelopes for each double/float constant used, then you can create a mapping between integer and double constants. Such mapping can be implemented e.g. as follows:
#include <string>
#include <sstream>
template<int index> double getValue()
{
std::stringstream ss("Not implemented for index ");
ss << index;
throw std::exception(ss.str());
}
template<> double getValue<0>() { return 3.6; }
template<> double getValue<1>() { return 7.77; }
template<int index> double multiply(double x)
{
return getValue<index>() * x;
}
Alternative options to implement the mapping are via a function which does switch-case on the input integer parameter and returns a float/double, or indexing to an array of constants, but both these alternatives would require constexpr for them to happen on compile-time, while some compilers still do not support constexpr: constexpr not compiling in VC2013

Related

C++ meta-function over templates

I have some templates like the ones below that I can use to define simple expressions
e.g.
Expr<constant,int,int,1,1> = 2
Expr<sub, Expr<constant,int,int,1,1>, Expr<constant,int,int,2,0>, 1, 1> = x - 2.
I want to define a meta-function that takes an Expr and returns another Expr that is a modified version of the one passed as input. The output will be based on the template arguments of the input so I guess I have to define multiple function templates that specialize different inputs. Eventually my goal is to be able to differentiate Expr's.
// the types of expressions (+,-,*, etc.)
enum ExprType { mul, divide, add, sub, constant};
// constant
template <ExprType eType, class Left, class Right, int coeff, int power> struct Expr {
static double eval(double x){
return coeff * std::pow(x, power);
}
};
//sub
template <class Left, class Right, int coeff, int power> struct Expr<sub, Left, Right, coeff, power> {
static double eval(double x){
return coeff * std::pow(Left::eval(x) - Right::eval(x), power);
}
};
// add
template <class Left, class Right, int coeff, int power> struct Expr<add, Left, Right, coeff, power> {
static double eval(double x){
return coeff * std::pow(Left::eval(x) + Right::eval(x), power);
}
};
However, I am having trouble wrapping my head around the function definition. So far I have:
template <template <ExprType eType, class Left, class Right, int coeff, int power> class E> struct ExprDerivative {
static E derivative(E e){
return e;
}
};
Am I going in the right direction? How do I define a meta-function over templates?
You want a type trait, which is a function with types as arguments. A type trait's definition looks nothing like a function on values (they're essentially written in a functional programming style, with "equations"), but they're called as you'd expect (func<args>).
template<typename Differentiand> struct derivative;
// shorthand for calling the function: derivative_t<expr...>
template<typename Differentiand>
using derivative_t = typename derivative<Differentiand>::result;
// every "equation" is a specialization of derivative for a certain set of Exprs that defines the result as a member type
template<typename L, typename R, int coeff, int power>
struct derivative<Expr<constant, L, R, coeff, power>> { using result = Expr<constant, L, R, coeff*power, power - 1> };
// etc
However, I am worried about how you've written the Expr type in the first place. constants are not constants; they're expressions of the form cx^n. Also, they have extraneous left and right operands. It would be better to do this
struct variable {
static constexpr double eval(double x) { return x; }
};
template<int Value>
struct constant {
static constexpr double eval(double x) { return Value; }
};
template<typename Left, typename Right>
struct addition {
static constexpr double eval(double x) { return Left::eval(x) + Right::eval(x); }
};
template<typename Left, typename Right>
struct multiplication {
static constexpr double eval(double x) { return Left::eval(x) * Right::eval(x); }
};
template<typename Base, int Power>
struct exponentiation {
static double eval(double x) { return std::pow(Base::eval(x), Power); }
};
// no need to add these as "primitives"
template<typename Left, typename Right>
using subtraction = addition<Left, multiplication<constant<-1>, Right>>;
template<typename Left, typename Right>
using division = multiplication<Left, exponentiation<Right, -1>>;
The results of differentiation do end up a little less simplified, but you can write another function to clean up after:
template<>
struct derivative<variable> { using result = constant<1>; };
template<int Value>
struct derivative<constant<Value>> { using result = constant<0>; };
template<typename L, typename R>
struct derivative<addition<L, R>> { using result = addition<derivative_t<L>, derivative_t<R>>; };
template<typename L, typename R>
struct derivative<multiplication<L, R>> { using result = addition<multiplication<derivative_t<L>, R>, multiplication<L, derivative_t<R>>>; };
template<typename B, int N>
struct derivative<exponentiation<B, N>> { using result = multiplication<multiplication<constant<N>, exponentiation<B, N - 1>>, derivative_t<B>>; };
E.g.
int main() {
// y = (x^2 + 1)/x
// dy/dx = 1 - x^-2
// dy/dx(x = 2) = 1 - 1/4 = 0.75
std::cout << derivative_t<division<addition<exponentiation<variable, 2>, constant<1>>, variable>>::eval(2) << "\n";
}
Not sure to understand what do you want... but sure you can't pass a template-template argument as a function argument.
Seems to me that your ExprDerivative() functional can be written, as template function that permit to deduce the template-template and the template parameters from the e argument, as follows
template <template <ExprType, typename, typename, int, int> class E,
ExprType eType, typename Left, typename Right,
int coeff, int power>
auto ExprDerivative (E<eType, Left, Right, coeff, power> e)
{ return e; }
Observe that, this way, the argument e is of type E<eType, Left, Right, coeff, power>, not of type E (that isn't a type).
You can use it, by example, as follows
Expr<constant, int, int, 1, 1> e0;
auto e1 = ExprDerivative(e0);

How to accumulate template parameter pack?

Suppose I want to enable writing this:
template <int a,int b> struct add_base{ static const int value = a+b;};
template<int...a> using add = accumulate<add_base,0,a...>;
template <int a,int b> struct mult_base{ static const int value = a*b;};
template<int...a> using mult = accumulate<mult_base,1,a...>;
template <int a,int b> struct sqsum_base{ static const int value = a+b*b;};
template<int...a> using sqsum = accumulate<sqsum_base,0,a...>;
static_assert( add<1,2,3>::value == 6 );
static_assert( mult<2,2,2>::value == 8 );
static_assert( sqsum<1,2,3>::value == 14 );
My accumulate looks like this:
template <template <int,int> class G,
int first, int second,
int...more>
struct accumulate {
static const int value = accumulate<G,G<first,second>::value,more...>::value;
};
template <template <int,int> class G,
int first, int second>
struct accumulate<G,first,second> {
static const int value = G<first,second>::value;
};
Now I wonder if accumulate can be condensed by expanding the recusion inline, something like:
template <template <int,int> class G,
int first,int second,
int...more>
struct accumulate {
static const int value = G< G<first,second>::value , more...>::value;
};
This is wrong and will result in
error: Wrong number of template arguments (3 should be 2)
Is it possible to unpack the parameters to instantiate G recursively in one line? If not, how to write accumulate without having to write a specialization?
If your compiler has support for C++17 then you may want to utilize fold expression:
template<int ... x_item> struct
accumulate
{
static inline constexpr int const s_value{(0 + ... + x_item)};
};
static_assert(6 == accumulate<1, 2, 3>::s_value);
online compiler
Example of parametrized operation:
template<typename x_Op, int ... x_items> struct
accumulate
{
static inline constexpr int const s_value{(x_Op{0} + ... + x_Op{x_items}).value};
};
struct
sq_sum
{
int value;
};
inline constexpr sq_sum
operator +(sq_sum left, sq_sum right)
{
return sq_sum{left.value + right.value * right.value};
}
static_assert(14 == accumulate<sq_sum, 1, 2, 3>::s_value);
online compiler

complex constexpr alternatives

Consider
typedef std::complex<double> Complex;
Complex ComplexExpresion(int a) {return Complex(0,-a);}
Since one cannot write
template<typename D>
struct A
{
static constexpr Complex value = ComplexExpresion(D::value);
};
as an alternative one writes
template<typename D>
struct B
{
static const Complex value;
};
template<typename D>
const Complex B<D>::value = ComplexExpresion(D::value);
Consider now
template<typename D, int N>
struct C;
template<typename D>
struct C<D,1>
{
static const Complex value;
};
template<typename D>
const Complex C<D,1>::value = B<D>::value;
For some reasone
struct Data
{
static auto constexpr value =2;
};
int main()
{
using C = C<Data,1>;
std::cout << C::value;
}
prints the correct value(which is (0,-2) ) here but the same code prints (0,0) when complied by MSVC++
I have 2 questions
1) why it is so on MSVC++ and is there known workaround?
2) is there better alternative for struct A than struct B which is not exactly the same thing...
Looks like a compiler bug unless I'm missing something. This isn't really an answer, just sharing what I found. This is the smallest example I could deduce that exhibits the issue:
#include <iostream>
// using function is important
int func() { return 1; }
// template is imporant
template<class D>
struct B
{
static const int value;
};
// defined outside block is important
template<class D>
const int B<D>::value = func();
// going through C is important
struct C
{
static const int value;
};
const int C::value = B<int>::value;
int main()
{
// should print 1 but prints 0
std::cout << C::value << std::endl;
}
surprisingly this also trips up clang unless I specify func as constexpr or specify -stdlib=libc++ (at least on coliru)
I guess you can fix your issue by skipping one of the bits above. You can do static constexpr Complex value = ComplexExpresion(D::value); if you mark ComplexEspression as constexpr.

C++ constexpr values for types

I want to be able to create switch statements over a type's ID. I've found a mechanism that could give a unique ID for different types. It's very simple:
template <typename T>
struct type {
static void id() { }
};
template <typename T>
constexpr const size_t type_id() {
return reinterpret_cast<size_t>(&type<T>::id);
}
I thought this would evaluate to a constant that I could use as cases for the switch. But I get an error that the case expression is not a constant when I do the following:
int main(void) {
size_t a = type_id<int>();
switch (a) {
case type_id<int>():
break;
}
return 0;
}
Why is it not a constant? How could I achieve this effect?
Edit:
Can I do something like this without the reinterpret_cast then?
I'm not sure it's a good idea but... just for fun... using the constexpr counter, suggested in this page, you should be able to substitute the value of the pointer.
The following is a (I repeat: just for fun) full experiment
#include <iostream>
template <int N>
struct flag
{ friend constexpr int adl_flag (flag<N>); };
template <int N>
struct writer
{
friend constexpr int adl_flag (flag<N>)
{ return N; }
static constexpr int value { N };
};
template <int N, int = adl_flag (flag<N> {})>
int constexpr reader (int, flag<N>)
{ return N; }
template <int N>
int constexpr reader (float, flag<N>, int R = reader (0, flag<N-1> {}))
{ return R; }
int constexpr reader (float, flag<0>)
{ return 0; }
template <int N = 1>
int constexpr next (int R = writer<reader (0, flag<32> {}) + N>::value)
{ return R; }
template <typename T>
struct type
{
static constexpr int id { next() };
constexpr static int type_id ()
{ return id; }
};
void printType (int idT )
{
switch ( idT )
{
case type<int>::type_id():
std::cout << "- int type" << std::endl;
break;
case type<long>::id:
std::cout << "- long type" << std::endl;
break;
default:
std::cout << "- another type" << std::endl;
break;
}
}
int main ()
{
int ii { type<int>::id };
int il { type<long>::type_id() };
printType(ii);
printType(il);
}
I would like to suggest another approach which involves constexpr functions and macros (eeeewww...):
// Some naive text hashing function
template <std::size_t SIZE>
constexpr std::size_t hash(const char (&type_name)[SIZE])
{
std::size_t result{0xf};
for (const auto &c : type_name)
{
result <<= 1;
result |= c;
}
return result;
}
First we create a constexpr function able to transform a string literal into a number, this is my approach but you can choose anoter function as long as it is constexpr, then we create a macro which stringify the given parameter using the #:
#define TYPE_ID(X) hash(#X)
And now, we can use it:
int main(void) {
size_t a = TYPE_ID(int);
switch (a) {
case TYPE_ID(int):
break;
}
return 0;
}
Pros:
Pretty straightforward.
Tiny amount of code.
Cons:
Macros.
Accepts any value, included nonsense: TYPE_ID(I LOVE BACON) is valid.
Yields different result for TYPE_ID(size_t) and TYPE_ID(unsigned long) even if they might be the same type.
constexpr functions can not use reinterpret_cast in any shape or form. Some more formal reading can be found at http://en.cppreference.com/w/cpp/language/constant_expression
This may solve your problem:
#include <tuple>
//Index from http://stackoverflow.com/a/18063608/3484570
template <class T, class Tuple>
struct Index;
template <class T, class... Types>
struct Index<T, std::tuple<T, Types...>> {
static const std::size_t value = 0;
};
template <class T, class U, class... Types>
struct Index<T, std::tuple<U, Types...>> {
static const std::size_t value = 1 + Index<T, std::tuple<Types...>>::value;
};
template <class T>
constexpr std::size_t type_id() {
//need to add every type in this tuple:
return Index<T, std::tuple<int, double, char>>::value;
}
int main() {
size_t a = type_id<int>();
switch (a) {
case type_id<int>():
break;
}
}
The good news is that you get a type_id<T>() that you can use in a constexpr context such as in a case like you wanted.
The bad news is that you need to list all supported types.
In practice you might get used to the error message that occurs when you ask for the type_id of an unsupported type and just add it and eventually add all relevant types.

c++ power of integer, template meta programming

I want to make a function which returns a power of integer.
Please read the fmuecke's solution in
power of an integer in c++ .
However, I want to generalize his solution to the arbitrary type T.
Since c++11 has constexpr, I guess this is possible.
Naively, I tried something like,
template<class T, int N>
inline constexpr T pow(const T x){
return pow<N-1>(x) * x;
}
template<class T>
inline constexpr T pow<T, 1>(const T x){
return x;
}
template<class T>
inline constexpr T pow<T, 0>(const T x){
return 1;
}
Actually this approach failed since the partial specialization for function template is not allowed.
And one more question. I heard that it is up to the compiler whether the constexpr function is evaluated in compile time or not.
How do I force it to compute for general type.
I read from somewhere that one of the simplest hack for integral consts is to wrap it in std::integral_const::value.
Solution using recursion:
#include <iostream>
template<class T>
inline constexpr T pow(const T base, unsigned const exponent)
{
// (parentheses not required in next line)
return (exponent == 0) ? 1 : (base * pow(base, exponent-1));
}
int main()
{
std::cout << "pow(2, 4): " << pow(2, 4) << std::endl;
std::cout << "pow(5, 0): " << pow(5, 0) << std::endl;
}
Jeremy W. Murphy suggested/requested a version using exponentiation by squaring:
template<class T>
inline constexpr T pow(const T base, unsigned const exponent)
{
// (parentheses not required in next line)
return (exponent == 0) ? 1 :
(exponent % 2 == 0) ? pow(base, exponent/2)*pow(base, exponent/2) :
base * pow(base, (exponent-1)/2) * pow(base, (exponent-1)/2);
}
"I heard that it is up to the compiler whether the constexpr function is evaluated in compile time or not."
True, AFAIK. The compiler isn't required to do constant-initialization at compile-time, but if you use the result of a constexpr function as a non-type template argument, it has to compute the result at compile-time.
std::cout << std::integral_constant<int, pow(2, 4)>::value << std::endl;
Also see the approach using integral_constant as parameter of pow in Andy Prowl's answer.
Here's how you can enforce compile-time evaluation:
#include <iostream>
#include <type_traits>
// insert a constexpr `pow` implementation, e.g. the one from above
template < typename T, T base, unsigned exponent >
using pow_ = std::integral_constant < T, pow(base, exponent) >;
// macro == error prone, you have been warned
#define POW(BASE, EXPONENT) (pow_ < decltype(BASE), BASE, EXPONENT > :: value)
int main()
{
std::cout << "pow(2, 4): " << pow_<int, 2, 4>::value << std::endl;
std::cout << "pow(2, 4): " << POW(2, 4) << std::endl;
}
Please leave a comment if you downvote so I can improve my answer.
When you find yourself in need of partially specializing a function template (beware, this does not mean that in this case you are in need, as DyP's answer shows), you may either resort to overloading (see the last update at the end of this answer) or, if that's not possible, wrap that function template into a class template, and have a static, non-template member function replace your original function template (and its specializations):
namespace detail
{
template<class T, int N>
struct helper
{
static constexpr T pow(const T x){
return helper<T, N-1>::pow(x) * x;
}
};
template<class T>
struct helper<T, 1> // Unnecessary specialization! (see the edit)
{
static constexpr T pow(const T x){
return x;
}
};
template<class T>
struct helper<T, 0>
{
static constexpr T pow(const T x){
return 1;
}
};
}
Then, you could provide a helper function template that delegates to the specialization of your helper class template:
template<int N, class T>
T constexpr pow(T const x)
{
return detail::helper<T, N>::pow(x);
}
Here is a live example.
EDIT:
Notice, that the specialization for N == 1 is actually not necessary. I kept it in the original text because the purpose of this answer was mainly to show how to workaround the impossibility of partially specializing function templates in general - so I translated the original program piece-by-piece.
As noted by Dyp in the comments, however, this would be enough:
namespace detail
{
template<class T, int N>
struct helper
{
static constexpr T pow(const T x){
return helper<T, N-1>::pow(x) * x;
}
};
template<class T>
struct helper<T, 0>
{
static constexpr T pow(const T x){
return 1;
}
};
}
UPDATE:
As a further remark, please keep in mind that even when you can specialize function templates (e.g. with explicit - not partial - specializations), it is generally not a good idea to do so, because function template specialization does not normally behave as one would expect.
Most of those situations that may seem to ask for function template specialization can actually be achieved through overloading, powered by well-known techniques such as tag dispatching. An example is proposed by Potatoswatter in the comments, pointing out that std::integral_constant could be used in this situation:
template<class T>
inline constexpr T pow(const T x, std::integral_constant<int, 0>){
return 1;
}
template<class T, int N>
inline constexpr T pow(const T x, std::integral_constant<int, N>){
return pow(x, std::integral_constant<int, N-1>()) * x;
}
template<int N, class T>
inline constexpr T pow(const T x)
{
return pow(x, std::integral_constant<int, N>());
}
However, all these guidelines on "how to solve problems that seem to require function template partial specialization" should be taken into consideration when they are really needed. In this concrete case, as DyP showed in his answer, they are not.
Here is a solution with a single function:
template <int N, class T>
constexpr T pow(const T& x)
{
return N > 1 ? x*pow<(N-1)*(N > 1)>(x)
: N < 0 ? T(1)/pow<(-N)*(N < 0)>(x)
: N == 1 ? x
: T(1);
}
Here is a simple solution:
#include<bits/stdc++.h>
using namespace std;
template<int N, int M>
struct Pow
{
enum { res = N * Pow<N,M-1>::res};
};
template<int N>
struct Pow<N,0>
{
enum {res = 1};
};
int main()
{
cout<<Pow<2,3>::res<<"\n";
}
Clean and simple solution here:
#include <cstddef>
template<size_t N, size_t P>
struct pow_constexpr { constexpr static auto value = N * pow_constexpr<N, P-1>::value; };
template<size_t N>
struct pow_constexpr<N, 1> { constexpr static auto value = N; };
template<size_t N>
struct pow_constexpr<N, 0> { constexpr static auto value = 1; };
int main() {
return pow_constexpr<2, 30>::value; // 1073741824
}