Can I force compiler to accept only a constexpr
or a non-variable input to a function?
I am looking for allowing only compile time values to a function. Either using template or any other method.
Here, there is a working example for int
templates. The problem with double
s is that they cannot be used as template arguments.
#include <iostream>
template <double x>
void show_x()
{
std::cout<<"x is always "<<x<<" in the entire program."<<std::endl;
}
int main()
{
show_x<10.0>();
return 0;
}
error: ‘double’ is not a valid type for a template non-type parameter
Update
To those who have marked this question as a duplicate, I have to say:
I ask question
How to solve problem A?
and
Solution B does not work for problem A, I need another solution
Then you linked me to why solution B
does not work.
That is totally illogical.
Here are 2 ways:
Update:
Concerns about user-circumvention have been addressed. Now, X::value()
s acquired by a constexpr
variable within the function body before being used. It is now not possible to pass an X
without a constexpr
method called value()
.
#include <iostream>
struct always_10
{
constexpr static double value() { return 10.0; }
};
template <class X>
void show_x()
{
constexpr auto x = X::value();
std::cout<<"x is always "<< x <<" in the entire program."<<std::endl;
}
template<class X>
void show_x(X x_)
{
constexpr auto x = x_.value();
std::cout<<"x is always "<< x <<" in the entire program."<<std::endl;
}
int main()
{
show_x<always_10>();
show_x(always_10());
return 0;
}
I'm not sure exactly what you want, but here is a way to reject non-constant expressions in a function call. Unfortunately it uses a macro which is bad because of name pollution, but maybe if you give your function a strange name then it won't hurt too much:
void f(double d) {}
#define f(x) do { constexpr decltype(x) var = x; f(var); } while (0)
int main()
{
f(1.0); // OK
f(1 + 2); // OK, constant expression with implicit conversion
double e = 5.0;
f(e); // compilation error, `e` is not a constant expression
}
If you want to reject constant expressions which aren't exactly double
type already, that would be possible too (not sure from your question whether that is a requirement).
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