以下错误通常不是语法错误本身,而是 Ceres 自带的 GTest 与所用 Eigen、或编译选项之间的不兼容导致宏/模板解析失败,进而把 it
识别成 void
类型。常见的几种解决思路如下:
1. 原因分析
-
Eigen 版本过高:Ceres 2.0.0 内部的测试(GTest)代码是在 Eigen 3.2.x 上开发验证的,若你用了 Eigen 3.3 及以上,可能会触发模板或宏冲突,使得
for (typename C::const_iterator it = container.begin(); …)
被误解析为
for (void it = …)
王(CSDN博客)。 -
测试代码编译:默认开启了
BUILD_TESTING
,会编译 Ceres 自带的示例和单元测试,这些测试里包含了旧版 GTest 的源码,也更依赖于旧版 Eigen 接口(Dol2's Dev Logs)。
2. 解决方案
2.1 禁用测试/示例编译
最简单直接:跳过编译 Ceres 的测试和示例,就不会触及到出错的 GTest 代码。
cd ceres-solver-build
cmake .. \
-DBUILD_TESTING=OFF \
-DBUILD_EXAMPLES=OFF
make -j$(nproc)
sudo make install
这样测试代码不会被编译,自然不会报 variable or field ‘it’ declared void
(CSDN博客)。
2.2 降级 Eigen 到 3.2.9
如果你确实需要编译 Ceres 的测试/示例,可将系统或项目中的 Eigen 回退到 3.2.9:
-
卸载或移动现有 Eigen(如 3.3/3.4)
-
从 Eigen 官网上 下载 3.2.9
-
解压到
/usr/local/include/eigen3
或项目内指定路径,然后重新cmake
构建 Ceres(CSDN博客)。
2.3 升级到已修复的 Ceres 版本
Debian 社区已在 ceres-solver 2.0.0+dfsg1-1
中修复了该问题(标记为已解决),可直接安装该发布版:
sudo apt-get update
sudo apt-get install ceres-solver=2.0.0+dfsg1-1
或从官方 GitHub 拉取最新 master
分支源码(包含修复补丁)重新编译安装(The Mail Archive, GitHub)。
2.4 手动 Undef 冲突宏(临时补丁)
如果你只想局部修复,也可在包含 gtest/gtest.h
之前,先 #undef it
:
#ifdef it
# undef it
#endif
#include <gtest/gtest.h>
这样可在源码层面消除 it
被误当宏替换为 void
的问题,但不建议长期采用(Stack Overflow)。
3. 推荐实施步骤
-
优先尝试禁用测试/示例:若你仅需在项目中使用 Ceres 求解器而不关心其自测,按 2.1 所述配置即可,一步到位。
-
仍需测试功能时降级 Eigen:在无法跳过测试需求下,按 2.2 降级 Eigen。
-
长远方案:升级 Ceres:无论禁不禁用测试,升级到官方已修复的 2.0.0+dfsg1-1 或更高版本,彻底根除该问题。
以上任一方案均能消除 ceres/gtest/gtest.h:10445:35: error: variable or field ‘it’ declared void
错误。如有疑问,可结合您的开发环境(Ubuntu 版本、Eigen 版本、CMake 选项)选择最适合的策略。