c++ - 将模板类型限制为枚举类
问题描述
下面的函数get_from_string
基本上string
通过创建 astringstream
并将其string
写入变量(的指针)来将 a 转换为变量。之后,它返回是否成功。如果变量是 a enum class
,它会绕过enum class
'underlying_type
并使用 astatic_cast
来达到相同的效果。
下面的代码完美运行,但我无法摆脱这两个get_from_string_helper_struct
s。我可以在没有任何辅助结构且仅使用函数的情况下解决此问题吗?
#include <iostream>
#include <sstream>
template <typename T, typename U = std::underlying_type_t<T>>
U to_underlying(T v) {
return static_cast<U>(v);
}
template <typename T, typename U = std::underlying_type_t<T>>
bool get_enum_from_string(T *target, const std::string &input) {
U n;
bool valid_input = static_cast<bool>(std::istringstream(input) >> n);
*target = static_cast<T>(n);
return valid_input;
}
template <typename T>
bool get_non_enum_from_string(T *target, const std::string &input) {
T n;
bool valid_input = static_cast<bool>(std::istringstream(input) >> n);
*target = n;
return valid_input;
}
template <typename T, class Enable = void>
struct get_from_string_helper_struct {
bool get(T *target, const std::string &input) {
return get_non_enum_from_string(target, input);
}
};
template <typename T>
struct get_from_string_helper_struct<
T, typename std::enable_if<std::is_enum<T>::value>::type> {
bool get(T *target, const std::string &input) {
return get_enum_from_string(target, input);
}
};
template <typename T>
bool get_from_string(T *target, const std::string &input) {
return get_from_string_helper_struct<T>().get(target, input);
}
enum class foo : uint8_t {
foo1 = 1,
foo2 = 2
};
int main(int argc, char const *argv[]) {
bool valid = false;
foo bar1;
valid = get_from_string(&bar1, "1");
std::cout << to_underlying(bar1) << (valid ? " True" : " False") << std::endl;
uint8_t bar2;
valid = get_from_string(&bar2, "1");
std::cout << bar2 << (valid ? " True" : " False") << std::endl;
return 0;
}
输出:
1 True
1 True
解决方案
使用 C++17,您可以这样做:
template <typename T>
bool get_from_string(T *target, const std::string &input) {
if constexpr (std::is_enum_v<T>) {
std::underlying_type_t<T> value{};
auto res = get_from_string(&value, input);
*target = static_cast<T>(value);
return res;
} else {
return static_cast<bool>(std::istringstream(input) >> *target);
}
}
演示。
推荐阅读
- ruby - 从 Array.product 填充的 Ruby Hash 产生意外行为
- powershell - 使用 powershell 从 ARM 模板 (.json) 中删除不需要的内容
- hybris - 将自定义后台扩展依赖项添加到另一个(外观)扩展时出现问题
- javascript - 使用 javascript 创建一个新的 Phabricator 任务
- ios - 仅在 iPhone 7 之前的设备上使用前置摄像头时崩溃
- kiwi-tcms - 关于备份kiwi-tcms数据库的一些问题
- swagger-ui - swagger-ui - 打开 api 3,multipart/form-data 数组问题
- mysql - 更新一个表中一个字段的所有记录,其值只在另一个表中
- elasticsearch - 用于弹性搜索的 Java 与 Python
- python - 在考虑 Python 列的同时使用 pandas.qcut