c++ - C++ 模板发送“错误参数”是一种不好的做法?
问题描述
std::stoi 在特定情况下会引发一些错误。我不想使用 try/catch 块,所以我在 google 上搜索了一些关于 char 转换的信息,发现这std::from_chars
正是我想要的,没有那些 try/catch 块。
显然,std::from_chars
直接使用效果很好,但我不喜欢这种语法。所以我开始编写自己的ToInt()
,ToFloat()
等。然后就像:“好吧,这听起来很愚蠢,让我们使用模板吧”。
我在这里 :
#include <string>
#include <charconv>
#include <iostream>
template <typename T>
T ToNumber(const char* str, T varType)
{
if (!str)
return 0;
T var = 0;
std::from_chars(str, str + strlen(str), var);
return var;
}
int main()
{
std::string t = "123.5";
auto a = ToNumber(t.c_str(), (int)0); // a will be an int (123)
float b = ToNumber(t.c_str(), (int)0); // b will store the value as int (123)
auto c = ToNumber(t.c_str(), (float)0); // c will be a float (123.5)
std::cout << a;
return 0;
}
它确实有效,这不是问题。但我想知道......发送“错误参数”(T varType
)以完成演员表并启用是一种好习惯auto
吗?
如果不是,那么编写这样一个函数的聪明方法是什么?
提前致谢
解决方案
您没有检查std::from_chars
失败的返回值,例如:
auto [p, ec] = std::from_chars(str, str + strlen(str), var);
if (ec != std::errc()) {
...
}
也就是说,在T
不使用类型转换的输入参数的情况下处理模板参数的另一种方法是简单地在调用站点显式指定所需的类型,例如:
template <typename T>
T ToNumber(const char* str)
{
if (!str)
return T{};
T var{};
auto [p, ec] = std::from_chars(str, str + strlen(str), var);
if (ec != std::errc())
return T{};
return var;
}
auto a = ToNumber<int>(t.c_str());
float b = ToNumber<int>(t.c_str());
auto c = ToNumber<float>(t.c_str());
否则,您可以通过引用输出参数使用模板参数推导(就像这样std::from_chars()
做一样),例如:
template <typename T>
bool ToNumber(const char* str, T &var)
{
if (!str)
return false;
auto [p, ec] = std::from_chars(str, str + strlen(str), var);
return (ec == std::errc());
}
int a;
ToNumber(t.c_str(), a);
int tmp;
ToNumber(t.c_str(), tmp);
float b = tmp;
float c;
ToNumber(t.c_str(), c);
推荐阅读
- php - 图像缩放到新宽度并保持质量和纵横比
- java - 从 Modelclass 层次结构的顶层调用 setter
- php - 小数点前 9 位和小数点后 1 到 3 位数字的正则表达式
- automation - 如何通过小袋鼠自动化浏览器回滚数据库中所做的更改
- postgresql - 如何在不嵌套输出的情况下将模型包含在 sequelize 中
- php - 将帖子与用户 ID 一起存储,参考 Laravel 6 中的用户表
- java - swt中的Scrollable和ScrolledComposite有什么区别?
- javascript - JavaScript 颜色数组
- c# - 带计数器的标签
- python - 图像和标签不会出现在 Tkinter 中