Consider I have a struct.
template<typename T>
struct Range{
T min, max;
Range() = default;
Range(T min = std::numeric_limits<T>::min(),T max = std::numeric_limits::max()) :
min(min), max(max){
}
};
So this struct holds a range for any type T, and if not given it the range becomes the numeric limits of that type.
Note: Of course I check for T
to be fundamental
type but this question is not about that.
Now in my use case I want to have a struct like this
template<typename T,Range<T>...ranges>
struct Something{
static std::array<Range<T>,sizeof...(ranges)> RANGES = {ranges...};
};
But when I want to "define" that something with this
using Defined = Something<int,Range<int>(100,200),Range<int>(200,300)>
I get compile-time error, because Range<T>
is non-type template parameter and I am not using C++ 20
. So I went further and updated my range struct like this.
template<typename T, T MIN = std::numeric_limits<T>::min(), T MAX = std::numeric_limits<T>::max()>
struct Range {
T min = MIN, max = MAX;
Range(T min, T max) : min(min), max(max) {}
Range() = default;
};
And my Something
struct's template becomes this typename<T,typename... Args>
so now using Defined = Something<int,Range<int,100,200>,Range<int,200,300>>
works. So at this point I've got 2 questions, how can I statically assert for each of args to be a Range<T,T min, T max>
. The second questions is about storing that. Look, I know that I have to store ...Args
in a tuple, but if you look at my implementation of Range, can I somehow wrap them in an std::array<Range<T>,sizeof(args)>
?
You can create trait
is_range
:and then fold expression (C++17)