I want to use if constexpr
instead of tag dispatching, but I am not sure how to use it. Example code below.
template<typename T>
struct MyTag
{
static const int Supported = 0;
};
template<>
struct MyTag<std::uint64_t>
{
static const int Supported = 1;
};
template<>
struct MyTag<std::uint32_t>
{
static const int Supported = 1;
};
class MyTest
{
public:
template<typename T>
void do_something(T value)
{
// instead of doing this
bool supported = MyTag<T>::Supported;
// I want to do something like this
if constexpr (T == std::uint64_t)
supported = true;
}
};
One way is to define a constexpr predicate which checks the type of its argument, then constexpr switch on the result of that predicate.
I think this way is nice because it separates the functional logic from the precondition logic.
#include <iostream>
#include <cstddef>
#include <type_traits>
class MyTest
{
public:
template<typename T>
void do_something(T value)
{
// define our predicate
// lambdas are constexpr-if-possible in c++17
constexpr auto is_supported = [](auto&& x) {
if constexpr (std::is_same<std::decay_t<decltype(x)>, std::uint64_t>())
return true;
else
return false;
};
// use the result of the predicate
if constexpr (is_supported(value))
{
std::cout << "supported\n";
}
else
{
std::cout << "not supported\n";
}
}
};
int main()
{
auto t = MyTest();
t.do_something(int(0));
t.do_something(std::uint64_t(0));
t.do_something(double(0));
t.do_something(static_cast<unsigned long>(0)); // be careful with std::uint_xx aliases
}
example results:
not supported
supported
not supported
supported
Another way to express this might be:
class MyTest
{
public:
template<class T>
static constexpr bool something_possible(T&&)
{
return std::is_same<std::decay_t<T>, std::uint64_t>();
}
template<typename T>
void do_something(T value)
{
// switch behaviour on result of constexpr predicate
if constexpr (something_possible(value))
{
std::cout << "supported\n";
}
else
{
std::cout << "not supported\n";
}
}
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With