可变参数模板,范围,C++

variadic template, Range, C++

假设我有一个结构。

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){
    } 
};

因此,此结构包含任何类型 T 的范围,如果未给它,则该范围将成为该类型的数字限制。 注意:当然我检查 Tfundamental 类型,但这个问题与此无关。

现在在我的用例中我想要一个这样的结构

template<typename T,Range<T>...ranges>
struct Something{
    static std::array<Range<T>,sizeof...(ranges)> RANGES = {ranges...};
};

但是当我想用这个来“定义”那个东西的时候 using Defined = Something<int,Range<int>(100,200),Range<int>(200,300)> 我收到编译时错误,因为 Range<T> 是非类型模板参数,我没有使用 C++ 20。所以我更进一步,像这样更新了我的范围结构。

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;
};

我的 Something 结构模板变成了这个 typename<T,typename... Args> 所以现在 using Defined = Something<int,Range<int,100,200>,Range<int,200,300>> 可以工作了。所以此时我有 2 个问题,我如何静态断言每个参数都是 Range<T,T min, T max>。第二个问题是关于存储的。看,我知道我必须将 ...Args 存储在一个元组中,但是如果你看一下我对 Range 的实现,我能以某种方式将它们包装在 std::array<Range<T>,sizeof(args)> 中吗?

您可以创建特征 is_range:

template <typename> struct is_range : std::false_type{};

template<typename T, T MIN, T MAX>
struct is_range<Range<T, MIN, MAX> : std::true_type{};

然后折叠表达式 (C++17)

template <typename ...Ts>
struct Something{
    static_assert((is_range<Ts>::value && ...));
    static std::tuple<Ts...> RANGES;
};