如果使用constexpr而不是标签分派 [英] if constexpr instead of tag dispatch
本文介绍了如果使用constexpr而不是标签分派的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我想使用if constexpr
代替标签分派,但是我不确定如何使用它.下面的示例代码.
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;
}
};
推荐答案
一种方法是定义一个constexpr谓词,该谓词检查其参数的类型,然后constexpr打开该谓词的结果.
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
}
示例结果:
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";
}
}
};
这篇关于如果使用constexpr而不是标签分派的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文