QT引用OpenCV出现错误:warpers_inl.hpp:146: error: C2589: “(”:“::”右边的非法标记

QT中出现这种重复定义的问题很正常

问题

QT中引入OpenCV在编译的时候出现了下面的问题:

1
2
3
4
F:\workspace\show\xhxzbzs\LiveEncoder\3rdparty\libopencv249\include\opencv2\stitching\detail\warpers_inl.hpp:146: error: C2589: “(”:“::”右边的非法标记
f:\workspace\show\xhxzbzs\liveencoder\3rdparty\libopencv249\include\opencv2\stitching\detail\warpers_inl.hpp(145): 编译类 模板 成员函数“void cv::detail::RotationWarperBase<cv::detail::PlaneProjector>::detectResultRoi(cv::Size,cv::Point &,cv::Point &)”时
f:\workspace\show\xhxzbzs\liveencoder\3rdparty\libopencv249\include\opencv2\stitching\detail\warpers_inl.hpp(68): 参见对正在编译的函数 模板 实例化“void cv::detail::RotationWarperBase<cv::detail::PlaneProjector>::detectResultRoi(cv::Size,cv::Point &,cv::Point &)”的引用
f:\workspace\show\xhxzbzs\liveencoder\3rdparty\libopencv249\include\opencv2\stitching\detail\warpers.hpp(130): 参见对正在编译的类 模板 实例化“cv::detail::RotationWarperBase<cv::detail::PlaneProjector>”的引用

出现问题的代码段

出现问题的代码段如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
template <class P>
void RotationWarperBase<P>::detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br)
{
float tl_uf = std::numeric_limits<float>::max();
float tl_vf = std::numeric_limits<float>::max();
float br_uf = -std::numeric_limits<float>::max();
float br_vf = -std::numeric_limits<float>::max();
float u, v;
for (int y = 0; y < src_size.height; ++y)
{
for (int x = 0; x < src_size.width; ++x)
{
projector_.mapForward(static_cast<float>(x), static_cast<float>(y), u, v);
tl_uf = std::min(tl_uf, u); tl_vf = std::min(tl_vf, v);
br_uf = std::max(br_uf, u); br_vf = std::max(br_vf, v);
}
}
dst_tl.x = static_cast<int>(tl_uf);
dst_tl.y = static_cast<int>(tl_vf);
dst_br.x = static_cast<int>(br_uf);
dst_br.y = static_cast<int>(br_vf);
}

出现问题的原因

std::numeric_limits()和std()中的函数模板max与Visual C++中的全局的宏max冲突。

Visual C++中的全局的宏函数模板max的代码如下:

1
2
3
4
5
template<class _Ty> inline
const _Ty& (__CLRCALL_OR_CDECL max)(const _Ty& _Left, const _Ty& _Right)
{ // return larger of _Left and _Right
return (_DEBUG_LT(_Left, _Right) ? _Right : _Left);
}

解决方法

方法一

设置项目属性,在预定义处理器中添加定义NOMINMAX来禁止使用Visual C++的min/max宏定义。
项目属性 ——> C/C++ ——> 预处理器 ——> 预处理器定义 (此处添加预定义编译开关 NOMINMAX)
但是visual C++中定义能自动匹配double和int,如果进行了上述设置,代码中手动将int型的数据乘以1.0来达到double的目的。
在QT中相当于在PRO文件中增加

1
DEFINES += NOMINMAX

方法二

将方法加括号,与Vsual C++的min/max宏定义区分开。例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
template <class P>
void RotationWarperBase<P>::detectResultRoi(Size src_size, Point &dst_tl, Point &dst_br)
{
float tl_uf = (std::numeric_limits<float>::max)();
float tl_vf = (std::numeric_limits<float>::max)();
float br_uf = -(std::numeric_limits<float>::max)();
float br_vf = -(std::numeric_limits<float>::max)();
float u, v;
for (int y = 0; y < src_size.height; ++y)
{
for (int x = 0; x < src_size.width; ++x)
{
projector_.mapForward(static_cast<float>(x), static_cast<float>(y), u, v);
tl_uf = (std::min)(tl_uf, u); tl_vf = (std::min)(tl_vf, v);
br_uf = (std::max)(br_uf, u); br_vf = (std::max)(br_vf, v);
}
}
dst_tl.x = static_cast<int>(tl_uf);
dst_tl.y = static_cast<int>(tl_vf);
dst_br.x = static_cast<int>(br_uf);
dst_br.y = static_cast<int>(br_vf);
}
Jerky Lu wechat
欢迎加入微信公众号