使用此辅助功能:
template<typename Type>
std::string toString(Type const& value, bool encloseInQuotes = false) {
if constexpr (std::is_same<bool, Type>::value) {
auto s = value ? "true" : "false";
return encloseInQuotes ? "\""s + s + "\"" : s;
}
if constexpr (std::is_arithmetic<Type>::value) {
if (std::isnan(value)) {
return encloseInQuotes ? "\"NaN\"" : "NaN";
}
}
return "";
}
应该将基本类型(和字符串)转换为字符串表达式,像这样使用MSVC时会出现编译错误:
int main() {
std::string temp = toString(true);
return 0;
}
使用clang可以毫无问题地进行编译,但是使用MSVC可以得到:
2> c:\ program files(x86)\ windows kits \ 10 \ include \ 10.0.10240.0 \ ucrt \ math.h(403):错误C2668:'fpclassify':对重载函数的歧义调用
2> c:\ program files(x86)\ windows kits \ 10 \ include \ 10.0.10240.0 \ ucrt \ math.h(288):注意:可能是'int fpclassify(long double)noexcept'
2> c:\ program files(x86)\ windows kits \ 10 \ include \ 10.0.10240.0 \ ucrt \ math.h(283):注意:或'int fpclassify(double)noexcept'
2> c:\ program files(x86)\ windows kits \ 10 \ include \ 10.0.10240.0 \ ucrt \ math.h(278):注意:或'int fpclassify(float)noexcept'
2> c:\ program files(x86)\ windows kits \ 10 \ include \ 10.0.10240.0 \ ucrt \ math.h(403):注意:在尝试匹配参数列表'(_Ty)'>
2>与
2> [
2> _Ty = int
2>]
2>:注意:请参见对正在编译的函数模板实例化'bool isnan(_Ty)noexcept'的引用
2>与
2> [
2> Type = int,
2> _Ty = int
2>]
很显然,编译器也认为if constexpr (std::is_arithmetic<Type>::value)
测试是有效的替代方法,并且会产生上述错误。但是,在运行时,它正确地采用了bool的路径(当我省略if constexpr (std::is_arithmetic<Type>::value)
部分或使用强制转换if (std::isnan(static_cast<double>(value)))
时)。
如何在Windows上也能正确编译?
答案 0 :(得分:7)
对于bool
,至少有两个类型特征返回true
:
std::is_same<bool, Type>::value
std::is_arithmetic<Type>::value
,然后拨打电话std::isnan(true)
。使用else if
:
if constexpr (std::is_same<bool, Type>::value) {
auto s = value ? "true" : "false";
return encloseInQuotes ? "\""s + s + "\"" : s;
}
else if constexpr (std::is_arithmetic<Type>::value) {
if (std::isnan(value)) {
return encloseInQuotes ? "\"NaN\"" : "NaN";
}
...
}
else
return "";
答案 1 :(得分:6)
std::isnan
和std::isinf
在MSVC中似乎在内部调用fpclassify
。对于浮点类型,此函数已重载,并且您传递了类型为bool
的参数,因此调用是模糊。
为避免这种情况,您可以将参数强制转换为double
:
if constexpr (std::is_arithmetic<Type>::value) {
if (std::isinf((double)value)) {
return encloseInQuotes ? "\"INF\"" : "INF";
}
if (std::isnan((double)value)) {
return encloseInQuotes ? "\"NaN\"" : "NaN";
}
实时演示:https://godbolt.org/z/W7Z3r3
更新
这似乎是MSVC实现中的错误,因为根据cppreference,对于整数参数,应该有与double
重载相同的重载。最小示例:
auto b = std::isnan(1);