catkin_make 编译时遇到这个问题:
/home/robot/ct_lio/src/ct-lio/src/common/eigen_types.h:114:20: error: the type ‘const zjloc::<lambda(const Vec2i&, const Vec2i&)>’ of ‘constexpr’ variable ‘zjloc::less_vec2i’ is not literal 114 | constexpr auto less_vec2i = | ^~~~ /home/robot/ct_lio/src/ct-lio/src/common/eigen_types.h:114:34: note: ‘zjloc::<lambda(const Vec2i&, const Vec2i&)>’ is not literal because: 114 | constexpr auto less_vec2i = | ^ cc1plus: note: ‘zjloc::<lambda(const Vec2i&, const Vec2i&)>’ is a closure type, which is only literal in C++17 and later In file included from /home/robot/ct_lio/src/ct-lio/src/tools/point_types.h:12, from /home/robot/ct_lio/src/ct-lio/src/preprocess/cloud_convert/cloud_convert.h:9, from /home/robot/ct_lio/src/ct-lio/src/preprocess/cloud_convert/cloud_convert.cc:1: /home/robot/ct_lio/src/ct-lio/src/common/eigen_types.h:114:20: error: the type ‘const zjloc::<lambda(const Vec2i&, const Vec2i&)>’ of ‘constexpr’ variable ‘zjloc::less_vec2i’ is not literal 114 | constexpr auto less_vec2i = | ^~~~ /home/robot/ct_lio/src/ct-lio/src/common/eigen_types.h:114:34: note: ‘zjloc::<lambda(const Vec2i&, const Vec2i&)>’ is not literal because: 114 | constexpr auto less_vec2i =
这个错误是因为代码中使用了一个 constexpr
lambda 表达式 less_vec2i
,但 lambda 表达式在 C++11 和 C++14 中并不是字面量类型(literal type),因此不能用于 constexpr
变量的定义。
解决方法:
1.升级到 C++17 或更高版本
在 C++17 中,lambda 表达式可以成为字面量类型,从而可以用于 constexpr
变量的定义。如果你的编译器支持,可以将代码标准提升到 C++17。
# 在 CMakeLists.txt 中设置编译标准为 C++17
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
2. 使用函数对象代替 lambda 表达式
如果不能升级到 C++17,可以将 lambda 表达式替换为具有 operator()
的结构体或类。这样的结构体或类可以在 C++11 和 C++14 中作为 constexpr
使用。
struct LessVec2i {constexpr bool operator()(const Vec2i &v1, const Vec2i &v2) const {// Your comparison logic herereturn v1.x() < v2.x() || (v1.x() == v2.x() && v1.y() < v2.y());}
};constexpr LessVec2i less_vec2i;
然后在需要使用的地方使用 less_vec2i
,如:
std::map<Vec2i, int, LessVec2i> my_map;
3. 避免使用 constexpr
如果不需要在编译时计算结果,可以将 constexpr
移除,将 lambda 表达式普通地定义为一个变量或函数。
auto less_vec2i = [](const Vec2i &v1, const Vec2i &v2) {return v1.x() < v2.x() || (v1.x() == v2.x() && v1.y() < v2.y());
};
然后在需要使用的地方直接使用 less_vec2i
。
总结
根据你的项目需要和编译器支持情况,选择适合的解决方案来修复 constexpr
lambda 表达式不是字面量类型的问题。通常推荐升级到支持 C++17 的编译器版本,以便能够更好地利用现代 C++ 的特性。