代码之家  ›  专栏  ›  技术社区  ›  SapphireSun

模板类型数学

  •  0
  • SapphireSun  · 技术社区  · 5 年前

    uint8_t 在其上执行需要 uint16_t 并发出较小的 uint8\u t 大堆

    对于 uint16\U t 输入我可能需要一个 uint32_t 阵列等。

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

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

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

    0 回复  |  直到 5 年前
        1
  •  3
  •   JeJo    5 年前

    在里面 ,您可以提供一个助手模板函数,您可以 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
  •  2
  •   Evg    5 年前

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

    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<T> .

        3
  •  2
  •   Aykhan Hagverdili    5 年前

    我们可以将int的大小作为模板参数,因此 Int<32> 表示32位整数。然后你可以做 Int<sizeof(other_int) * 8 * 2> ,这意味着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; 
    }