deducing non-type template argument type from template function argument

84 views Asked by At

I have a template function parametrized by a compile-time constant whose type should be the same as the type of the function argument.

For instance, I'm seeking to have this kind of syntax:

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

Non working Live

This dummy function is taking some runtime value x and a compile-time constant, that I want to be of the same type as x (let say it is an integral type), and tells if x is greater or equal than its limit.

How can I achieve that (C++14 if possible, C++17 at most)?

2

There are 2 answers

15
LiuYuan On BEST ANSWER

With auto template argument in C++17, things will do:

#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
Jarod42 On

C++14 doesn't have auto as template parameter.

You might turn your template parameter into function argument:

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