如何拥有受约束的运算符模板?
How can I have a constrained operator template?
我正在尝试使我的类可转换为任何枚举类型。
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;
使转换模板不适用于模板参数无法推断:
它不能以你的方式推导,因为这里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
,而不是其他任何东西。
相关文章:
- 为什么比较运算符如此快速
- C++映射:具有自定义类的运算符[]不起作用(总是返回0)
- IpOpt拒绝解决不受约束的问题
- 受约束的成员函数和显式模板实例化
- 如何拥有受约束的运算符模板?
- 无法在赋值运算符中访问基类的受保护方法
- 为什么重载解析更喜欢不受约束的模板函数而不是更具体的模板函数?
- 函数不受主内存约束的函数所需的复杂性是什么?
- 如何通过运算符<<的重载访问受保护的功能?C++
- 受保护成员与重载运算符冲突
- 如何调整由两点定义的线的大小,使其受C++的最大线长度的约束
- C++运算符重载和受保护字段
- 抽象类中受保护的流运算符
- 受模式约束的最长公共子字符串
- 数据结构受比较器约束
- c++调用约定是否受标准约束,因为在声明fn时不需要定义函数的返回类型
- 输出一个结构指针和一个受约束的结构成员
- 未定义的行为-是用其他语言编写的函数,受C++关于UB的规则的约束
- 类层次结构中的受约束构造函数,C++
- 什么是受约束的模板