我正在尝试使我的班级可转换为任何枚举类型。
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;
答案 0 :(得分:3)
无法推断出转换为模板参数所无法使用的模板:
不能用您的方式推论它,因为T
在这里是非推论上下文:
template< typename T > using Enum = enable_if_t< is_enum_v< T >, 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;
请注意,别名必须为T
,而不是其他任何东西。