【问题标题】:Workaround for the lack of support for type alias specialization in C++在 C++ 中缺少对类型别名专业化的支持的解决方法
【发布时间】:2023-03-19 13:22:01
【问题描述】:

我希望能够使用文字作为 id 来引用不同的类型。

template<auto>
using type = void;

template<>
using type<0> = int;

template<>
using type<1> = char;

template<>
using type<2> = string;

int main()
{
  type<0> var0;
  type<1> var1;
  type<2> var2;
}

这会导致编译器给我错误,因为 C++ 尚不支持类型别名专门化。 (实现这种功能所需的技术根本不存在)

【问题讨论】:

    标签: c++ template-specialization type-alias


    【解决方案1】:

    这样就可以了,并且会给你你需要的语法。请注意,我明确使用 std::size_t 来避免专门化其他类型而不是数字。

    #include <string>
    #include <type_traits>
    
    //-------------------------------------------------------------------
    // hide all the boiler plate in a namespace
    // use structs for partial specializations
    
    namespace details
    {
        template<std::size_t N>
        struct type_s { using type = void; };
    
        template<> struct type_s<0> { using type = int; };
        template<> struct type_s<1> { using type = char; };
        template<> struct type_s<2> { using type = std::string; };
    }
    
    //-------------------------------------------------------------------
    // now you can use a full template for alias
    
    template<std::size_t N>
    using type_t = typename details::type_s<N>::type;
    
    //-------------------------------------------------------------------
    
    int main()
    {
        type_t<0> var0{ 42 };
        type_t<1> var1{ 'A' };
        type_t<2> var2{ "Hello World!" };
    
        static_assert(std::is_same_v<type_t<0>, int>);
        static_assert(std::is_same_v<type_t<1>, char>);
        static_assert(std::is_same_v<type_t<2>, std::string>);
    
        static_assert(std::is_same_v<decltype(var0), int>);
        static_assert(std::is_same_v<decltype(var1), char>);
        static_assert(std::is_same_v<decltype(var2), std::string>);
    }
    

    【讨论】:

      【解决方案2】:

      别名模板中不允许部分特化,但是,您可以改用std::conditional

      #include <type_traits>
      #include <string>
      // ...
      
      template <auto X>
      using type = std::conditional_t<X == 0, int,
                   std::conditional_t<X == 1, char,
                   std::conditional_t<X == 2, std::string,
                       void>>>;
      

      【讨论】:

      • 你好,我的工具箱的另一个工具
      【解决方案3】:

      幸运的是,我找到了一种解决方法,它使用了 C++ 支持的类专业化

      template<auto>
      struct TypeAliasWrapper;
      
      template<>
      struct TypeAliasWrapper<0>{using type = int;};
      
      template<>
      struct TypeAliasWrapper<1>{using type = char;};
      
      template<>
      struct TypeAliasWrapper<2>{using type = string;};
      
      int main()
      {
        TypeAliasWrapper<0>::type var0;
        TypeAliasWrapper<1>::type var1;
        TypeAliasWrapper<2>::type var2;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-03-16
        • 2016-01-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-01-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多