在linux和windows上std :: min/max类型扣除不同

Ela*_*782 8 c++ gcc opencv stl visual-c++

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

以下适用于Windows VS2013,并在GCC-4.8上给出了编译错误:(参见下面的错误)

int minX = max(min(floor(v1[0]), min(floor(v2[0]), floor(v3[0]))), 0.0f);
Run Code Online (Sandbox Code Playgroud)

这在GCC-4.8上编译,但在VS2013上给出了编译错误:(见下面的错误)

int minX = max(min(floor(v1[0]), min(floor(v2[0]), floor(v3[0]))), 0.0);
Run Code Online (Sandbox Code Playgroud)

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

从OpenCV开始,cv :: Vec3f是a Vec<float, 3>Vec's运算符[]

const _Tp& operator [](int i) const;
_Tp& operator[](int i);
Run Code Online (Sandbox Code Playgroud)

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

所以当我写作

int minX = max(min(floor(v1[0]), min(floor(v2[0]), floor(v3[0]))), 0.0f);
Run Code Online (Sandbox Code Playgroud)

类型应该是

max(min(float, min(float, float), float);
Run Code Online (Sandbox Code Playgroud)

那么为什么海湾合作委员会会在这里纾困?

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'
Run Code Online (Sandbox Code Playgroud)

GCC-4.8出错:

error: no matching function for call to 'max(const double&, float)'
Run Code Online (Sandbox Code Playgroud)

回答:

GCC没有使用std :: floor而是使用全局命名空间(由cmath绘制).如果我添加using std::floor,所有代码按预期工作!令人讨厌的双层(...)函数在全局命名空间中!

Vla*_*cow 3

如果不是拼写错误那么在这个声明中

int minX = max(min(floor(v1[0]), min(floor(v2[0]), floor(v3[0]))), 0.0);
Run Code Online (Sandbox Code Playgroud)

整数文字9.9具有类型double,而其他操作数具有浮点类型。所以编译器无法决定是否使用模板参数floatdouble

错误消息清楚地表明了对于功能

'const _Ty &std::max(const _Ty &,const _Ty &)' 
Run Code Online (Sandbox Code Playgroud)

那里could be 'double' or 'float'

这是函数调用看起来像

std::max( float_value, double_value );
Run Code Online (Sandbox Code Playgroud)

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

std::max<double>( float_value, double_value );
Run Code Online (Sandbox Code Playgroud)

或者

std::max<float>( float_value, double_value );
Run Code Online (Sandbox Code Playgroud)

至于 GCC,它将floor具有返回类型的标准 C 函数放置double在全局命名空间中。

double floor(double x);
Run Code Online (Sandbox Code Playgroud)

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

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

我认为如果你使用限定名称std::floor 那么 GCC 也会发出错误。

所以在你的代码中 MS VC++ 使用函数

float floor(float x);
Run Code Online (Sandbox Code Playgroud)

结果在 GCC 使用函数时发出错误

double floor(double x);
Run Code Online (Sandbox Code Playgroud)

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