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

如何获得约束运算符模板?

  •  1
  • zdf  · 技术社区  · 6 年前

    我试图使我的类转换为任何枚举类型。

    enum dst_1 { /*...*/ };
    enum dst_2 { /*...*/ };
    class src { /*...*/ };
    
    src s;
    dst_1 d1 = s;
    dst_2 d2 = s;
    

    我愿意 不想手动 为每个枚举类型添加转换,因此以下是不可接受的解决方案:

    // OK, but tedious - you must consider each enum type
    class src
    {
    public:
      operator dst_1() const { /*...*/ }
      operator dst_2() const { /*...*/ }
      // ...
    };
    

    将转换设置为模板不适用于模板参数 :

    // NOT OK: T cannot be deduced
    class src
    {
    public:
      template< typename T > using Enum = enable_if_t< is_enum_v< T >, T >;
      template< typename T > operator Enum< T >() const { /*...*/ }
    };
    

    这个 我能找到的唯一解决办法是可变模板

    // ALMOST OK, but still tedious - you must know in advance what enums will be used
    src< dst_1, dst_2 > s;
    dst_1 d1 = s;
    dst_2 d2 = s;
    

    理想情况下,我想写:

    src s;
    dst_1 d1 = s;
    dst_2 d2 = s;
    
    1 回复  |  直到 6 年前
        1
  •  3
  •   Barry    6 年前

    将转换设置为模板不起作用,因为无法推断模板参数:

    你这样做是无法推断的,因为 T 这里是一个非推断的上下文:

    template< typename T > using Enum = enable_if_t< is_enum_v< T >, T >;
    

    :

    template <typename T> struct identity { using type = T; }
    
    template <typename T> void foo(typename identity<T>::type);
    foo(0); // nope
    

    编写此运算符模板的正确方法是:

    template <typename T, std::enable_if_t<std::is_enum_v<T>, int> = 0>
    operator T() const;
    

    template <typename T, std::enable_if_t<std::is_enum_v<T>, int> = 0> using Enum = T;
    template <typename T> operator Enum<T>() const;
    

    请注意,别名 ,不是别的。