C++ 可以推断非类型模板参数的类型并强制其余模板参数的类型吗?

Tom*_*ica 1 c++ templates auto c++17 non-type-template-parameter

考虑这个结构。它是一个范围,但使用模板而不是构造函数,使值静态:

template <int min_v, int max_v>
struct num_range final {
  constexpr static int min = min_v;
  constexpr static int max = max_v;
}
// now you can do
std::cout << num_range<1,3>::min << '\n'; // prints 1
Run Code Online (Sandbox Code Playgroud)

但这是固定的int。如果我希望 C++ 从第一个参数推导数字类型并将其强制应用于第二个参数,该怎么办?

我试过这个:

template <typename TNumber>
template <TNumber min_v, TNumber max_v>
struct num_range final 
Run Code Online (Sandbox Code Playgroud)

我按照相反的顺序尝试了。我知道你可以这样做:

template <auto min_v, decltype(min_v) max_v>
struct num_range final {
    using num_type = decltype(min_v);
    constexpr static num_type min = min_v;
    constexpr static num_type max = max_v;
};
Run Code Online (Sandbox Code Playgroud)

但我认为autoC++17 中不允许使用模板参数,这正是我的目标。它似乎也没有强制第二个模板参数的类型,因为它编译得很好:

std::cout << num_range<-10, 12U>::min << '\n'; // prints -10
Run Code Online (Sandbox Code Playgroud)

如果您知道如何使用可变模板执行此操作,强制所有数字为同一类型,那就加分了。

Hol*_*Cat 6

我认为 C++17 中不允许使用自动模板参数

C++17 中允许这样做。

它似乎也没有强制第二个模板参数的类型

是的,传递模板参数时允许进行一些隐式转换。改为这样做:

template <auto min_v, auto max_v>
struct num_range
{
    static_assert(std::is_same_v<decltype(min_v), decltype(max_v)>);
    constexpr static auto min = min_v;
    constexpr static auto max = max_v;
};
Run Code Online (Sandbox Code Playgroud)

或者在 C++20 中:

template <auto min_v, auto max_v>
requires std::is_same_v<std::is_same_v<decltype(min_v), decltype(max_v)>
struct num_range
{
    constexpr static auto min = min_v;
    constexpr static auto max = max_v;
};
Run Code Online (Sandbox Code Playgroud)