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

多个嵌套的std::u?

  •  2
  • NoSenseEtAl  · 技术社区  · 8 年前

    我发现很多嵌套的std::conditionalΒ很难阅读,所以我选择了一种不同的模式(用自动返回类型对函数调用decltype):

    template<bool is_signed, std::size_t has_sizeof>
    auto find_int_type(){
        static_assert(sizeof(int)==4);
        if constexpr(is_signed){
            if constexpr(has_sizeof==4){
                return int{};
            } else if constexpr (has_sizeof==8){
                return std::int64_t{};
            } else {
                return;
            }
        } else {
            if constexpr(has_sizeof==4){
                return (unsigned int){};
            }
            else if constexpr (has_sizeof==8){
                return std::uint64_t{};
            } else {
                return;
            }
        } 
    }
    
    static_assert(std::is_same_v<int, decltype(find_int_type<true, 4>())>);
    static_assert(std::is_same_v<unsigned int, decltype(find_int_type<false, 4>())>);
    static_assert(std::is_same_v<void, decltype(find_int_type<false, 3>())>);
    static_assert(std::is_same_v<void, decltype(find_int_type<false, 5>())>);
    static_assert(std::is_same_v<std::int64_t, decltype(find_int_type<true, 8>())>);
    static_assert(std::is_same_v<std::uint64_t, decltype(find_int_type<false, 8>())>);
    static_assert(std::is_same_v<void, decltype(find_int_type<false, 9>())>);
    

    我的问题是:

    有更好的方法吗?

    这种方式的编译速度是否比std::conditional\t慢(假设我需要实例化的类型比这个示例中只使用内置类型的扩展性要大得多)。

    2 回复  |  直到 8 年前
        1
  •  6
  •   Toby Speight    8 年前

    template<bool is_signed, std::size_t has_sizeof>
    struct find_int_type_impl { using type = void; }; // Default case
    
    template<> struct find_int_type_impl<true,  4> { using type = std::int32_t;  };
    template<> struct find_int_type_impl<true,  8> { using type = std::int64_t;  };
    template<> struct find_int_type_impl<false, 4> { using type = std::uint32_t; };
    template<> struct find_int_type_impl<false, 8> { using type = std::uint64_t; };
    
    template<bool is_signed, std::size_t has_sizeof>
    using find_int_type = typename find_int_type_impl<is_signed, has_sizeof>::type;
    
        2
  •  1
  •   cpplearner    8 年前

    因为 std::disjunction<Args...> 从中的第一个类型继承 Args... value true ,或者如果不存在此类类型,则 ,我们可以(ab)使用它来生成多路分支:

    template<class... Args>
    using select = typename std::disjunction<Args...>::type;
    
    template<bool V, class T>
    struct when {
        static constexpr bool value = V;
        using type = T;
    };
    
    template<bool is_signed, std::size_t has_sizeof>
    using find_int_type = select<
        when<is_signed, select<
            when<has_sizeof==4, int>,
            when<has_sizeof==8, std::int64_t>,
            when<false, void>
        >>,
        when<!is_signed, select<
            when<has_sizeof==4, unsigned int>,
            when<has_sizeof==8, std::uint64_t>,
            when<false, void>
        >>
    >;