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