【问题标题】:Conditional template type math条件模板类型数学
【发布时间】:2020-08-16 04:36:05
【问题描述】:

我有一个 C++ 函数,它接收一个 uint8_t 数组,在其上执行各种需要 uint16_t 的函数,并发出一个较小的 uint8_t 数组。

对于uint16_t 输入,我可能需要uint32_t 数组等。

有没有办法使用模板建立这种关系?类似的东西(在伪代码中):

template <typename T, typename U = sizeof(T) * 2>

不幸的是,我实际上是在混合使用,因此无法避免大量的复制粘贴,但我想知道在某些情况下这是否是一种选择。

【问题讨论】:

    标签: cython c++ c++ templates types template-meta-programming function-templates


    【解决方案1】:

    中,你可以提供一个帮助模板函数,你可以通过decltype找到你想要返回的数组的返回类型。

    #include <cstdint>
    #include <type_traits> // std::is_same_v
    
    template <typename T> 
    auto ret_type_helper()
    {
       if constexpr (std::is_same_v <T, std::uint8_t>)         return std::uint16_t{};
       else if constexpr (std::is_same_v <T, std::uint16_t>)   return std::uint32_t{};
       else if constexpr (std::is_same_v <T, std::uint32_t>)   return std::uint64_t{};
       // else if constexpr... for another type.....
    }
    
    template <typename T>
    auto func(const std::array<T /*, size */>& arr)
    {
       // use for getting the array's type, which you want to return from the function
       using ReType = decltype(ret_type_helper<T>());
    
       std::array<ReType /*, size */> result;
    
       // ... code
       return result;
    }
    

    【讨论】:

      【解决方案2】:

      您无法自动完成,但通过一些手动操作是可能的:

      template<typename> struct double_size_type;
      
      template<> struct double_size_type<std::uint8_t> {
          using type = std::uint16_t;
      };
      
      template<> struct double_size_type<std::uint16_t> {
          using type = std::uint32_t;
      };
      
      template<> struct double_size_type<std::uint32_t> {
          using type = std::uint64_t;
      };
      
      template<typename T, typename U = typename double_size_type<T>::type> {
          // ...
      };
      

      对于每个受支持的类型T,您需要提供double_size_type&lt;T&gt; 的特化。

      【讨论】:

      • 我会删除第二个模板参数并将其替换为函数内部的using U = typename ...;。用户不应该能够覆盖U
      【解决方案3】:

      我们可以将 int 的大小作为模板参数,所以Int&lt;32&gt; 表示 32 位整数。然后就可以做Int&lt;sizeof(other_int) * 8 * 2&gt;了,意思是int的大小是other_int的两倍:

      #include <cstdint>
      #include <type_traits>
      
      // signed
      template <std::size_t size>
      using Int = std::conditional_t<size==8, std::int8_t,
                      std::conditional_t<size==16, std::int16_t,
                          std::conditional_t<size==32, std::int32_t,
                              std::conditional_t<size==64, std::int64_t, void>>>>;
      
      // unsigned
      template <std::size_t size>
      using UInt = std::conditional_t<size==8, std::uint8_t,
                      std::conditional_t<size==16, std::uint16_t,
                          std::conditional_t<size==32, std::uint32_t,
                              std::conditional_t<size==64, std::uint64_t, void>>>>;
      
      int main() { 
          // twice size of a regular int
          Int<sizeof(int) * 8 * 2> i2 = 0; 
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-10-27
        • 2021-12-08
        • 2017-05-20
        • 1970-01-01
        • 1970-01-01
        • 2013-12-09
        相关资源
        最近更新 更多