从模板函数参数推断非类型模板参数类型

deducing non-type template argument type from template function argument

提问人:Oersted 提问时间:10/3/2023 更新时间:10/4/2023 访问量:66

问:

我有一个模板函数,由编译时常量参数化,其类型应与函数参数的类型相同。

例如,我正在寻求这种语法:

#include <cstdint>
#include <limits>

using mytype_t = std::uint8_t;
constexpr mytype_t Min = 0;

template <typename T, T limit>
bool GreaterThanLimit(T const x) {
    if constexpr (limit > std::numeric_limits<T>::min()) {
        return (limit <= x);
    } else {
        return true;
    }
}

int main() {
    mytype_t x = 42;
    // KO
    bool v = GreaterThanLimit<Min>(x);
    static_cast<void>(v);
}

非工作直播

这个虚拟函数采用一些运行时值和一个编译时常量,我希望它与 x 具有相同的类型(假设它是一个整数类型),并告诉它是否大于或等于其限制。xx

我怎样才能实现这一点(如果可能的话,C++14,最多C++17)?

c++ 推导 函数模板 非类型模板参数

评论


答:

2赞 LiuYuan 10/3/2023 #1

使用 C++17 中的自动模板参数,事情会做:

#include <cstdint>
#include <limits>
#include <type_traits>

using mytype_t = std::uint8_t;
constexpr mytype_t Min = 0;

template <auto limit, typename T> bool GreaterThanLimit(T const x) {
  static_assert(std::is_same_v<decltype<limit>,T>);

  if constexpr (limit > std::numeric_limits<T>::min()) {
    return (limit <= x);
  } else {
    return true;
  }
}

int main() {
  int x = 42;

  // Works
  bool v = GreaterThanLimit<Min>(x);
  static_cast<void>(v);
}
❯ g++ -std=c++17 test.cpp -o test
❯ ./test
❯ echo $?
0

评论

0赞 463035818_is_not_an_ai 10/3/2023
C++17 特有的推论是什么?
0赞 463035818_is_not_an_ai 10/3/2023
你的意思是 C++17 中引入的模板参数吗?auto
0赞 LiuYuan 10/3/2023
@463035818_is_not_an_ai 我的错,我把这两件事混为一谈。
0赞 463035818_is_not_an_ai 10/3/2023
OP 还要求“函数正在接受一些运行时值 x 和一个编译时常量,我希望与 x 具有相同的类型”,但您只需采用任何类型和传入的任何类型Minx
0赞 LiuYuan 10/3/2023
@463035818_is_not_an_ai 更新,真诚的感谢
3赞 Jarod42 10/3/2023 #2

C++14 没有模板参数。auto

您可以将模板参数转换为函数参数:

template <typename T, T limit>
bool GreaterThanLimit(std::integral_constant<T, limit>, T x)
{
    return limit <= x;
}

using mytype_t = std::uint8_t;
constexpr std::integral_constant<mytype_t, 0> Min{};

int main() {
    mytype_t x = 42;
    [[maybe_unused]] bool v = GreaterThanLimit(Min, x);
}