无法在枚举类模板参数的底层类型上调用is_unsigned的问题
问题修复方案
你的代码错误出在依赖类型的typename缺失,结合C++17及以上的特性优化后,修正代码如下:
#include <type_traits> template <class E> concept EnumAddSubtract = std::is_enum_v<E> && std::is_unsigned_v<typename std::underlying_type<E>::type> && requires { E::AddSubtract; }; template <EnumAddSubtract E> constexpr E operator+(E const& lhs, int const& rhs) { using Underlying = typename std::underlying_type<E>::type; return static_cast<E>(static_cast<Underlying>(lhs) + static_cast<Underlying>(rhs)); }
如果使用C++20,还可以用std::underlying_type_t进一步简化(它是typename std::underlying_type<T>::type的内置别名):
#include <type_traits> template <class E> concept EnumAddSubtract = std::is_enum_v<E> && std::is_unsigned_v<std::underlying_type_t<E>> && requires { E::AddSubtract; }; template <EnumAddSubtract E> constexpr E operator+(E const& lhs, int const& rhs) { using Underlying = std::underlying_type_t<E>; return static_cast<E>(static_cast<Underlying>(lhs) + static_cast<Underlying>(rhs)); }
关键修改说明
- 添加
typename关键字:在模板中,std::underlying_type<E>::type属于依赖模板参数E的类型,编译器无法自动识别它是类型还是成员变量,必须显式加typename前缀。 - 使用
_v后缀的类型 trait:std::is_unsigned_v<T>是C++17新增的简写形式,等价于std::is_unsigned<T>::value,让代码更简洁。 - 类型别名复用:用
using Underlying定义底层类型的别名,避免重复书写冗长的类型声明。
内容的提问来源于stack exchange,提问作者GLJeff
相关产品推荐
相关产品推荐

