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<¶m>();
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<¶m>();
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! ;)
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;
}
This works for me:
template <double* pVar>
double fun()
{
return *pVar;
}
double param = 1.2;
int main() {
double value = fun<¶m>();
return 0;
}
I'm using g++ 4.8.2.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With