I am learning concepts, and I can not figure out a way to restrain the value (not type) of non-type template parameter.
Example of code that compiles, although I wish it did not(due to failed requirement):
#include <cassert>
enum Bla{
Lol,
Haha
};
template<Bla b>
requires requires{
// my guess is that this just checks that this is valid expression, not
// that it is true
b>1;
}
void f(){
assert(b>1);
}
int main() {
f<Lol>(); // compiles, not funny ;)
}
Note:
this is simplified example( I want "template overloading") so static_assert
is not good for me, and I am trying to avoid std::enable_if
since syntax is hideous.
Which parameter is legal for non-type template? Explanation: The following are legal for non-type template parameters:integral or enumeration type, Pointer to object or pointer to function, Reference to object or reference to function, Pointer to member.
A template parameter is a special kind of parameter that can be used to pass a type as argument: just like regular function parameters can be used to pass values to a function, template parameters allow to pass also types to a function.
For example, given a specialization Stack<int>, “int” is a template argument. Instantiation: This is when the compiler generates a regular class, method, or function by substituting each of the template's parameters with a concrete type.
NoneType is the type for the None object, which is an object that indicates no value. None is the return value of functions that "don't return anything".
If you only have a boolean condition and nothing else, do this:
template<Bla b>
requires(b > 1)
void f() {}
Alternative longer syntax, if you need to check more things in the same requires
-expression:
template<Bla b>
requires requires
{
requires b > 1;
// ^~~~~~~~
}
void f() {}
Since f
needs to be constrained only by the value of the non-type template parameter, you can simply write a requires
clause instead of an ad-hoc requires requires
constraint:
template<Bla b>
requires (b>1)
void f() {}
Here's a demo.
You only need a requires requires
expression if you want to do more complicated checks on the template parameter. In that case, I recommend using a named concept over an ad-hoc constraint anyway. This makes the code more readable, and allows you to reuse the concept in other places.
As for assert
, it's a run-time construct, so it doesn't affect compilation in any way, assuming the expression inside the assert
is syntactically valid. You need to use static_assert
instead, if you want to check the template parameter at compile time:
static_assert(b>1);
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