Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I pass floating point numbers as template parameters?

Tags:

c++

I am working on a meta-programming project, and we would like to have the ability to pass floating-point numbers as template arguments. I wasn't sure whether this question would be better suited to Stack Exchange, but I figured it's a somewhat conceptual so opted for this site.

Basically, I want to do this:

template <double var>
double fun() { return var; }

int main()
{
  double myDoble = fun<1.0>();
  return 0;
}

Obviously, this can't be done. This link (http://en.cppreference.com/w/cpp/language/template_parameters) makes it clear that the type passed as a template argument must be one of the following:

integral type
enumeration
pointer to object or to function
lvalue reference to object or to function
pointer to member object or to member function
std::nullptr_t (since C++11)

However, the fact that I can pass a pointer to an object (perhaps a pointer to a struct containing a double?) makes me wonder that there might be a way of achieving the above by passing a pointer to such a double.

So I tried this:

template <double* pVar>
double fun()
{
    return *pVar;
}

int main() {
    static const double param = 1.2;
    double value = fun<&param>();
    return 0;
}

which gives the following error:

prog.cpp:9:29: error: ‘& param’ is not a valid template argument of type ‘double*’ because ‘param’ has no linkage
  double value = fun<&param>();

I thought that the issue might be that I'm using a primitive, so I tried this:

struct D
{
    double val;
};

template <D* pD>
double fun()
{
    return pD->val;
}

int main() {
    static const D d{1.2};

    double value = fun<&d>();
    return 0;
}

which gives the same error.

Does anyone have other ideas for approaching this problem? I would appreciate it if people could refrain from "it can't be done" answers; I know it can't be done, I want to do it anyway! ;)

like image 653
quant Avatar asked Jan 10 '23 04:01

quant


2 Answers

If you really want to pass double's to templated function, you should use a wrapper. Like this one:

struct D
{
    operator double(){ return 1.2; }
};

template <typename T>
double fun()
{
    T t;
    return t;
}

int main()
{
    double value = fun<D>();
    return 0;
}

but maybe more useful is to define a macro like this:

#define DBLWRAPPER(dbl) typedef struct { operator double(){ return dbl; } }

int main()
{
    DBLWRAPPER(1.2) DBL1_2;
    DBLWRAPPER(2.45) DBL2_45;

    double value1_2 = fun<DBL1_2>();
    double value2_45 = fun<DBL2_45>();
    return 0;
}
like image 84
user270049 Avatar answered Jan 23 '23 11:01

user270049


This works for me:

template <double* pVar>
double fun()
{
    return *pVar;
}

double param = 1.2;

int main() {
   double value = fun<&param>();
   return 0;
}

I'm using g++ 4.8.2.

like image 35
R Sahu Avatar answered Jan 23 '23 12:01

R Sahu