如果使用constexpr而不是标签分派 [英] if constexpr instead of tag dispatch

查看:124
本文介绍了如果使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆