c++ - std::min/max 类型推导在 linux 和 windows 上不同

标签 c++ opencv visual-c++ gcc stl

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

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

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

这在 GCC-4.8 上编译但在 VS2013 上给出编译错误:(错误见下文)

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的 operator[] 是

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

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

所以当我写的时候

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

类型应该是

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

那么为什么 GCC 退出这里呢?

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: no matching function for call to 'max(const double&, float)'

回答:

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

最佳答案

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

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

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

错误信息说清楚了函数

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

可能是“double”或“float”

函数调用看起来像

std::max( float_value, double_value );

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

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

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

对于 GCC 然后它将返回类型为 double 的标准 C 函数 floor 放置在全局命名空间中。

double floor(double x);

所以应用这个函数后的操作数被转换为double类型。但是好像MS VC++并没有把这个函数放到全局命名空间或者MS VC++的全局命名空间有重载的同名函数。

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

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

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

float floor(float x);

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

double floor(double x);

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

关于c++ - std::min/max 类型推导在 linux 和 windows 上不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25086999/

相关文章:

opencv - 使用 C++ 从打开的 cv 中的图像中访问元素

opencv - 如何在 OpenCV 中定义分水岭的标记?

c++ - _bstr_t 到 UTF-8 可能吗?

c++模板从接口(interface)多重继承

字符串的 C++ fwrite 和 fread

c++ - 模板匹配屏幕截图在断言时失败

c++ - C++ 是否强制我定义默认构造函数

.net - 用 VC++ 开发的程序何时需要在目标计算机上安装 .NET Framework,何时需要 MS VC++ Redistributable Package?

c++ - 流外 : can't convert to ofstream&

c# - 可以使用 Boost 或 STL 显示自定义字符串的 C++ 断言?