【发布时间】:2019-01-31 16:43:05
【问题描述】:
我正在尝试学习一些关于模板和元函数的知识,即std::enable_if。我正在为我们的学校作业(课外活动,请注意)制作菜单系统,并且需要一种从用户那里获取输入的方法。我想为各种类型的输入定义一个模板类 - 使用如下:
std::string userInput = Input<std::string>("What's your name?").Show();
float userHeight = Input<float>("How tall are you?").Show();
我想(我确信有理由不这样做,但尽管如此)使用std::stringstream 进行这种广义的转换:从用户那里获取输入,输入 SS,提取到 T 类型的变量.
在运行时查看转换是否失败很容易,但我想使用std::enable_if 来防止人们在无法转换的情况下使用我的Input<> class,比如:
std::vector<Boats> = Input<std::vector<>>("Example").Show();
显然std::stringstream 无法将字符串转换为向量,所以它总是会失败。
我的问题是这样的:
我可以将std::enable_if 子句格式化为仅允许为上面列出的类型实例化我的模板类吗?或者,有没有更好的方法来解决它?我是不是完全搞错了?
到目前为止我做了什么
我相信我找到了std::stringstream 可以将字符串“转换”为的允许类型列表:
http://www.cplusplus.com/reference/istream/istream/operator%3E%3E/
到目前为止,我一直像这样使用std::enable_if:
template <typename T, typename = typename
std::enable_if<std::is_arithmetic<T>::value, T>::type>
但是,现在我想扩展它,不仅允许算术值,还允许 sstream >> 运算符支持的所有值。
【问题讨论】:
-
为什么不能将字符串转换为向量?编写流运算符将向量转换为字符串并返回非常简单。如果未定义运算符,那么无论如何您都会收到编译器错误,因此 SFINAE 真的不会为您带来任何好处。
-
@NathanOliver 这就是我一直需要帮助的原因——如果流操作符被扩展,如果我的输入函数允许无缝扩展就好了。否则我也许可以手动过滤允许的类型,但这似乎是一个糟糕的解决方法。你是对的,错误使用它会导致编译器错误,但我想学习如何检测这些东西 - 也许使用 static_assert 来打印合适的错误,而不是 enable_if。
-
好的。
static_asset是与 SFINAE 不同的场景。 SFINAE 仍然可以给你可怕的错误信息。至少你有几个答案可以让你使用static_assert
标签: c++ templates sfinae stringstream enable-if