C++:除decltype(枚举成员)外,获取枚举类型的其他可行方法
问题:获取枚举类型的替代方法(除了
decltype(enum_name::any_value)) 我定义了如下枚举:
enum HTTPRequestMethods {GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE, PATCH};
为了能通过编写新接口实现即可替换代码中的任意网络库,同时出于性能需求(因此选择C++而非Python,即便用Python最快的库仍不够快),我计划采用CRTP模式编写接口。
此外,为减少运行时分支,我希望为URL使用模板,为每个HTTPRequestMethod编写特定函数:
template <decltype(HTTPRequestMethods::GET) Method> struct URL { explicit URL(std::string web_url, std::string path) : web_url(web_url), path(path) {} std::string web_url; std::string path; }; template <typename InterfaceImplementation> struct InternetInterface { template <decltype(HTTPRequestMethods::GET) HTTPRequestMethod> std::string_view getBody(URL<HTTPRequestMethod> url) { return static_cast<InterfaceImplementation*>(this)->getBody<HTTPRequestMethod>(url); } }; struct APIWrapper : InternetInterface<APIWrapper> { ... template <decltype(HTTPRequestMethods::GET) HTTPRequestMethod> std::string_view getBody(URL<HTTPRequestMethod> url_); private: ... }; // template specializations: // for GET template <> std::string_view APIWrapper::getBody(URL<HTTPRequestMethods::GET> url) { ... } ...
请问除了使用decltype(enum_name::any_value)之外,还有其他获取枚举类型的方法吗?
回答
当然有几种更直接、可读性更强的方式来获取枚举类型,无需依赖枚举的具体值:
1. 直接使用枚举类型名
这是C模板中处理枚举参数的标准写法,C11及以后完全支持。直接将枚举类型作为模板参数的类型约束,代码更直观且类型安全性更高:
// 直接用HTTPRequestMethods作为模板参数类型 template <HTTPRequestMethods Method> struct URL { explicit URL(std::string web_url, std::string path) : web_url(web_url), path(path) {} std::string web_url; std::string path; }; // 接口定义同步简化 template <typename InterfaceImplementation> struct InternetInterface { template <HTTPRequestMethods HTTPRequestMethod> std::string_view getBody(URL<HTTPRequestMethod> url) { return static_cast<InterfaceImplementation*>(this)->getBody<HTTPRequestMethod>(url); } }; // APIWrapper中的模板声明也同步调整 struct APIWrapper : InternetInterface<APIWrapper> { ... template <HTTPRequestMethods HTTPRequestMethod> std::string_view getBody(URL<HTTPRequestMethod> url_); ... }; // 特化写法保持不变,依然清晰 template <> std::string_view APIWrapper::getBody(URL<HTTPRequestMethods::GET> url) { ... }
这种方式的优势在于:编译器会自动校验模板实参是否属于HTTPRequestMethods枚举的合法值,避免传入非法整数的风险,而decltype(HTTPRequestMethods::GET)本质是枚举的底层整数类型(默认是int),无法提供这种类型校验。
2. 自定义枚举类型别名(语法糖)
如果枚举名称过长,可以先定义一个短别名再使用,本质和第一种方法一致,但能简化代码:
using HttpMethod = HTTPRequestMethods; template <HttpMethod Method> struct URL { // 实现同前 };
3. 获取枚举底层类型(仅特定场景适用)
如果需要的是枚举对应的底层整数类型(而非枚举类型本身),可以用std::underlying_type_t<HTTPRequestMethods>,但这通常用于枚举与整数的转换场景,并不匹配你当前需要约束模板参数为合法枚举值的需求。
内容的提问来源于stack exchange,提问作者arniiiii_ua
相关产品推荐
相关产品推荐

