std :: min/max类型推导在Linux和Windows上不同 [英] std::min/max type deduction different on linux and windows

查看:204
本文介绍了std :: min/max类型推导在Linux和Windows上不同的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在下面的代码中,std :: min/max的模板类型推导似乎很奇怪,我想知道为什么以及如何正确修复它.

In the following code, the template type deduction for std::min/max seems to be weird and I'd like to know why and how to properly fix it.

以下内容在Windows VS2013上有效,并且在GCC-4.8上给出了编译错误:(有关错误,请参见下文)

The following works on Windows VS2013, and gives a compile-error on GCC-4.8: (see below for the error)

int minX = max(min(floor(v1[0]), min(floor(v2[0]), floor(v3[0]))), 0.0f);

这可以在GCC-4.8上编译,但是在VS2013上却出现编译错误:(有关错误,请参见下文)

And this compiles on GCC-4.8 but gives a compile-error on VS2013: (see below for the error)

int minX = max(min(floor(v1[0]), min(floor(v2[0]), floor(v3[0]))), 0.0);

v[1-3]cv::Vec3f v1, v2, v3;

来自OpenCV,cv :: Vec3f是Vec<float, 3>,而Vec的运算符[]是

from OpenCV, a cv::Vec3f is a Vec<float, 3> and Vec's operator[] is

const _Tp& operator [](int i) const;
_Tp& operator[](int i);

min/max/floor/ceil来自std ::名称空间(即代码顶部的using std::min等).

The min/max/floor/ceil are from the std:: namespace (i.e. using std::min etc. at the top of the code).

所以当我写

int minX = max(min(floor(v1[0]), min(floor(v2[0]), floor(v3[0]))), 0.0f);

类型应为

max(min(float, min(float, float), float);

那为什么GCC会在这里纾困?

So why does GCC bail out here?

VS2013错误:

error C2782: 'const _Ty &std::max(const _Ty &,const _Ty &)' : template parameter '_Ty' is ambiguous
          C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include\algorithm(4086) : see declaration of 'std::max'
          could be 'double' or 'float'

GCC-4.8错误:

Error on GCC-4.8:

error: no matching function for call to 'max(const double&, float)'

答案:

GCC不是使用std :: floor,而是从全局名称空间(由cmath绘制)中选择.如果添加using std::floor,则所有代码均按预期工作!全局名称空间中令人讨厌的double(...)函数!

GCC wasn't using std::floor but floor from the global namespace (drawn in by cmath). If I add using std::floor, all the code works as expected! Nasty double floor(...) function in the global namespace!

推荐答案

如果不是拼写错误,则在此声明中

If it is not a typo then in this statement

int minX = max(min(floor(v1[0]), min(floor(v2[0]), floor(v3[0]))), 0.0);

整数文字9.9的类型为double,而其他操作数的类型为float.因此,编译器无法决定使用模板参数float还是double

integer literal 9.9 has type double while other operands have type float. So the compiler can not decide whether to use template argument float or double

错误消息说清楚了,对于功能

The error message says clear that for function

'const _Ty &std::max(const _Ty &,const _Ty &)' 

could be 'double' or 'float'

这是funcrion调用的样子

That is the funcrion call looks as

std::max( float_value, double_value );

例如,您可以显式指定模板参数

You could explicitly specify the template argument as for example

std::max<double>( float_value, double_value );

std::max<float>( float_value, double_value );

对于GCC,然后它将具有返回类型double的标准C函数floor放置在全局名称空间中.

As for GCC then it places the standard C function floor that has return type double in the global namespace..

double floor(double x);

因此,应用此函数后的操作数将转换为double类型.但是似乎MS VC ++不会将此函数放在全局命名空间中,或者MS VC ++中的全局命名空间具有重载的同名函数.

So the operands after applying this function are converted to the type double. But it seems that MS VC++ does not places this function in the global namespace or the global namespace in MS VC++ has overloaded functions with the same name.

因此问题与每个编译器在全局名称空间中放置的函数有关.

So the problem is relative to what function(s) floor each compiler places in the global namespace.

我认为,如果您使用限定名称std::floor,那么GCC也会发出错误消息.

I think that if you used qualified name std::floor then GCC would also issue an error.

所以在您的代码中,MS VC ++使用了功能

So in your code MS VC++ uses function

float floor(float x);

并且结果在GCC使用功能时发出错误

and as the result issues the error while GCC uses function

double floor(double x);

和函数std::max的所有操作数都具有double类型,并且代码已成功编译.:)

and all operands of function std::max have type double and the code is compiled successfully.:)

这篇关于std :: min/max类型推导在Linux和Windows上不同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆