Error Log: type parameters of <T>T cannot be determined; no unique maximal instance exists for ...

本文探讨了在Maven环境中遇到的一种特定编译错误,并详细分析了错误原因。该错误涉及类型参数不匹配的问题,特别是在泛型方法调用中。通过调整代码逻辑,解决了返回类型不一致导致的编译失败问题。

测试环境Maven编译工程时候报以下错误:

type parameters of <T>T cannot be determined; no unique maximal instance exists for type variable T with upper bounds int,java.lang.Object

而开发环境却编译正常,经查代码:

public <T> T selectOne(String statement);

public int countXXX() {
	...
	return selectOne("YYY");
}

发现countXXX()的返回类型int与selectOne的返回类型定义不一致。

网上有“升级Java版本”的解决方案。不过,这样的代码毕竟不严谨,一旦出现null,必然报错。

我的解决方案是修改代码,尽量不要报异常:

public int countXXX() {
	...
	Integer count = selectOne("YYY");
	return count == null ? -1 : count.intValue();
}
另外,也可以将countXXX()的返回类型int,修改为Integer。

#ifndef MTKMATH_H_ #define MTKMATH_H_ #include <cmath> #include <boost/math/tools/precision.hpp> #include "../types/vect.hpp" #ifndef M_PI #define M_PI 3.1415926535897932384626433832795 #endif namespace MTK { namespace internal { template<class Manifold> struct traits { typedef typename Manifold::scalar scalar; enum {DOF = Manifold::DOF}; typedef vect<DOF, scalar> vectorized_type; typedef Eigen::Matrix<scalar, DOF, DOF> matrix_type; }; template<> struct traits<float> : traits<Scalar<float> > {}; template<> struct traits<double> : traits<Scalar<double> > {}; } // namespace internal /** * \defgroup MTKMath Mathematical helper functions */ //@{ //! constant @f$ \pi @f$ const double pi = M_PI; template<class scalar> inline scalar tolerance(); template<> inline float tolerance<float >() { return 1e-5f; } template<> inline double tolerance<double>() { return 1e-11; } /** * normalize @a x to @f$[-bound, bound] @f$. * * result for @f$ x = bound + 2\cdot n\cdot bound @f$ is arbitrary @f$\pm bound @f$. */ template<class scalar> inline scalar normalize(scalar x, scalar bound){ //not used if(std::fabs(x) <= bound) return x; int r = (int)(x *(scalar(1.0)/ bound)); return x - ((r + (r>>31) + 1) & ~1)*bound; } /** * Calculate cosine and sinc of sqrt(x2). * @param x2 the squared angle must be non-negative * @return a pair containing cos and sinc of sqrt(x2) */ template<class scalar> std::pair<scalar, scalar> cos_sinc_sqrt(const scalar &x2){ using std::sqrt; using std::cos; using std::sin; static scalar const taylor_0_bound = boost::math::tools::epsilon<scalar>(); static scalar const taylor_2_bound = sqrt(taylor_0_bound); static scalar const taylor_n_bound = sqrt(taylor_2_bound); assert(x2>=0 && "argument must be non-negative"); // FIXME check if bigger bounds are possible if(x2>=taylor_n_bound) { // slow fall-back solution scalar x = sqrt(x2); return std::make_pair(cos(x), sin(x)/x); // x is greater than 0. } // FIXME Replace by Horner-Scheme (4 instead of 5 FLOP/term, numerically more stable, theoretically cos and sinc can be calculated in parallel using SSE2 mulpd/addpd) // TODO Find optimal coefficients using Remez algorithm static scalar const inv[] = {1/3., 1/4., 1/5., 1/6., 1/7., 1/8., 1/9.}; scalar cosi = 1., sinc=1; scalar term = -1/2. * x2; for(int i=0; i<3; ++i) { cosi += term; term *= inv[2*i]; sinc += term; term *= -inv[2*i+1] * x2; } return std::make_pair(cosi, sinc); } template<typename Base> Eigen::Matrix<typename Base::scalar, 3, 3> hat(const Base& v) { Eigen::Matrix<typename Base::scalar, 3, 3> res; res << 0, -v[2], v[1], v[2], 0, -v[0], -v[1], v[0], 0; return res; } template<typename Base> Eigen::Matrix<typename Base::scalar, 3, 3> A_inv_trans(const Base& v){ Eigen::Matrix<typename Base::scalar, 3, 3> res; if(v.norm() > MTK::tolerance<typename Base::scalar>()) { res = Eigen::Matrix<typename Base::scalar, 3, 3>::Identity() + 0.5 * hat<Base>(v) + (1 - v.norm() * std::cos(v.norm() / 2) / 2 / std::sin(v.norm() / 2)) * hat(v) * hat(v) / v.squaredNorm(); } else { res = Eigen::Matrix<typename Base::scalar, 3, 3>::Identity(); } return res; } template<typename Base> Eigen::Matrix<typename Base::scalar, 3, 3> A_inv(const Base& v){ Eigen::Matrix<typename Base::scalar, 3, 3> res; if(v.norm() > MTK::tolerance<typename Base::scalar>()) { res = Eigen::Matrix<typename Base::scalar, 3, 3>::Identity() - 0.5 * hat<Base>(v) + (1 - v.norm() * std::cos(v.norm() / 2) / 2 / std::sin(v.norm() / 2)) * hat(v) * hat(v) / v.squaredNorm(); } else { res = Eigen::Matrix<typename Base::scalar, 3, 3>::Identity(); } return res; } template<typename scalar> Eigen::Matrix<scalar, 2, 3> S2_w_expw_( Eigen::Matrix<scalar, 2, 1> v, scalar length) { Eigen::Matrix<scalar, 2, 3> res; scalar norm = std::sqrt(v[0]*v[0] + v[1]*v[1]); if(norm < MTK::tolerance<scalar>()){ res = Eigen::Matrix<scalar, 2, 3>::Zero(); res(0, 1) = 1; res(1, 2) = 1; res /= length; } else{ res << -v[0]*(1/norm-1/std::tan(norm))/std::sin(norm), norm/std::sin(norm), 0, -v[1]*(1/norm-1/std::tan(norm))/std::sin(norm), 0, norm/std::sin(norm); res /= length; } } template<typename Base> Eigen::Matrix<typename Base::scalar, 3, 3> A_matrix(const Base & v){ Eigen::Matrix<typename Base::scalar, 3, 3> res; double squaredNorm = v[0] * v[0] + v[1] * v[1] + v[2] * v[2]; double norm = std::sqrt(squaredNorm); if(norm < MTK::tolerance<typename Base::scalar>()){ res = Eigen::Matrix<typename Base::scalar, 3, 3>::Identity(); } else{ res = Eigen::Matrix<typename Base::scalar, 3, 3>::Identity() + (1 - std::cos(norm)) / squaredNorm * hat(v) + (1 - std::sin(norm) / norm) / squaredNorm * hat(v) * hat(v); } return res; } template<class scalar, int n> scalar exp(vectview<scalar, n> result, vectview<const scalar, n> vec, const scalar& scale = 1) { scalar norm2 = vec.squaredNorm(); std::pair<scalar, scalar> cos_sinc = cos_sinc_sqrt(scale*scale * norm2); scalar mult = cos_sinc.second * scale; result = mult * vec; return cos_sinc.first; } /** * Inverse function to @c exp. * * @param result @c vectview to the result * @param w scalar part of input * @param vec vector part of input * @param scale scale result by this value * @param plus_minus_periodicity if true values @f$[w, vec]@f$ and @f$[-w, -vec]@f$ give the same result */ template<class scalar, int n> void log(vectview<scalar, n> result, const scalar &w, const vectview<const scalar, n> vec, const scalar &scale, bool plus_minus_periodicity) { // FIXME implement optimized case for vec.squaredNorm() <= tolerance() * (w*w) via Rational Remez approximation ~> only one division scalar nv = vec.norm(); if(nv < tolerance<scalar>()) { if(!plus_minus_periodicity && w < 0) { // find the maximal entry: int i; nv = vec.cwiseAbs().maxCoeff(&i); result = scale * std::atan2(nv, w) * vect<n, scalar>::Unit(i); return; } nv = tolerance<scalar>(); } scalar s = scale / nv * (plus_minus_periodicity ? std::atan(nv / w) : std::atan2(nv, w) ); result = s * vec; } } // namespace MTK #endif /* MTKMATH_H_ */ 详细注释上述代码
最新发布
09-30
以下是对 `mtkmath.hpp` 文件的 **全面技术解析**,涵盖流形数学工具、泰勒展开优化和特殊矩阵运算的详细注释: --- ### **文件结构与基础定义** ```cpp #ifndef MTKMATH_H_ #define MTKMATH_H_ #include <cmath> // 标准数学函数 #include <boost/math/tools/precision.hpp> // Boost精度控制工具 #include "../types/vect.hpp" // 自定义向量类型 #ifndef M_PI #define M_PI 3.1415926535897932384626433832795 // 定义π常量 #endif namespace MTK { namespace internal { ``` - **精度控制**:使用Boost库的`epsilon<scalar>()`获取机器精度 - **π常量**:跨平台兼容性定义 --- ### **类型特征萃取模板** ```cpp template<class Manifold> struct traits { typedef typename Manifold::scalar scalar; // 流形的标量类型 enum {DOF = Manifold::DOF}; // 流形自由度 typedef vect<DOF, scalar> vectorized_type; // 向量化类型 typedef Eigen::Matrix<scalar, DOF, DOF> matrix_type; // 对应矩阵类型 }; // 标量类型特化 template<> struct traits<float> : traits<Scalar<float>> {}; template<> struct traits<double> : traits<Scalar<double>> {}; ``` - **设计意图**:统一流形与标量的类型接口 - **典型应用**:在模板函数中自动获取类型的数学特性 --- ### **核心数学工具函数** #### **1. 归一化函数** ```cpp template<class scalar> inline scalar normalize(scalar x, scalar bound) { if(std::fabs(x) <= bound) return x; int r = (int)(x *(scalar(1.0)/ bound)); // 巧妙的位运算实现周期映射 return x - ((r + (r>>31) + 1) & ~1)*bound; } ``` - **数学原理**:将输入值映射到`[-bound, bound]`区间 - **优化技巧**:用整数运算替代浮点取模(`r>>31`处理负数) #### **2. 泰勒展开优化三角函数** ```cpp template<class scalar> std::pair<scalar, scalar> cos_sinc_sqrt(const scalar &x2) { static scalar const taylor_0_bound = boost::math::tools::epsilon<scalar>(); static scalar const taylor_2_bound = sqrt(taylor_0_bound); static scalar const taylor_n_bound = sqrt(taylor_2_bound); if(x2>=taylor_n_bound) { // 常规计算 scalar x = sqrt(x2); return std::make_pair(cos(x), sin(x)/x); } // 小角度泰勒展开(保留3阶项) scalar cosi = 1., sinc=1; scalar term = -1/2. * x2; for(int i=0; i<3; ++i) { cosi += term; // cos(x) ≈ 1 - x²/2! + x⁴/4! - ... term *= inv[2*i]; // 预计算倒数表优化 sinc += term; // sinc(x) ≈ 1 - x²/3! + x⁴/5! - ... term *= -inv[2*i+1] * x2; } return std::make_pair(cosi, sinc); } ``` - **动态切换策略**:根据输入大小选择泰勒展开或直接计算 - **数值优化**:预计算系数倒数减少除法开销 #### **3. SO(3)流形运算** ```cpp // 叉乘矩阵生成(李代数→李群) template<typename Base> Eigen::Matrix<typename Base::scalar, 3, 3> hat(const Base& v) { Eigen::Matrix<typename Base::scalar, 3, 3> res; res << 0, -v[2], v[1], v[2], 0, -v[0], -v[1], v[0], 0; return res; } // 右雅可比矩阵逆(用于ESKF更新) template<typename Base> Eigen::Matrix<typename Base::scalar, 3, 3> A_matrix(const Base & v) { double norm = v.norm(); if(norm < tolerance<typename Base::scalar>()) { return Eigen::Matrix<typename Base::scalar, 3, 3>::Identity(); } return Eigen::Matrix<typename Base::scalar, 3, 3>::Identity() + (1 - std::cos(norm)) / squaredNorm * hat(v) + (1 - std::sin(norm)/norm) / squaredNorm * hat(v) * hat(v); } ``` - **几何意义**:`A_matrix`实现旋转向量→旋转矩阵的指数映射 - **奇点处理**:小角度时返回单位矩阵避免除零 #### **4. S²流形运算** ```cpp template<typename scalar> Eigen::Matrix<scalar, 2, 3> S2_w_expw_(Eigen::Matrix<scalar, 2, 1> v, scalar length) { scalar norm = v.norm(); if(norm < tolerance<scalar>()) { Eigen::Matrix<scalar, 2, 3> res = Eigen::Matrix<scalar, 2, 3>::Zero(); res(0, 1) = res(1, 2) = 1; // 单位矩阵的切空间投影 return res / length; } // 球面指数映射微分 res << -v[0]*(1/norm-1/std::tan(norm))/std::sin(norm), norm/std::sin(norm), 0, -v[1]*(1/norm-1/std::tan(norm))/std::sin(norm), 0, norm/std::sin(norm); return res / length; } ``` - **应用场景**:处理平面特征等二维流形 - **数值稳定**:显式处理`norm→0`的极限情况 --- ### **指数/对数映射** ```cpp // 流形指数映射(向量→流形) template<class scalar, int n> scalar exp(vectview<scalar, n> result, vectview<const scalar, n> vec, const scalar& scale = 1) { std::pair<scalar, scalar> cos_sinc = cos_sinc_sqrt(scale*scale * vec.squaredNorm()); result = cos_sinc.second * scale * vec; // 向量部分 return cos_sinc.first; // 标量部分(cos值) } // 流形对数映射(流形→切空间) template<class scalar, int n> void log(vectview<scalar, n> result, const scalar &w, const vectview<const scalar, n> vec, const scalar &scale, bool plus_minus_periodicity) { scalar nv = vec.norm(); if(nv < tolerance<scalar>()) { if(!plus_minus_periodicity && w < 0) { int i; nv = vec.cwiseAbs().maxCoeff(&i); // 处理180°旋转歧义 result = scale * std::atan2(nv, w) * vect<n, scalar>::Unit(i); return; } nv = tolerance<scalar>(); } result = (scale / nv * (plus_minus_periodicity ? std::atan(nv/w) : std::atan2(nv, w))) * vec; } ``` - **周期性处理**:`plus_minus_periodicity`参数控制是否识别`Q`和`-Q`为相同旋转 - **奇点优化**:小角度时采用泰勒展开近似 --- ### **关键数值处理技术** 1. **动态精度阈值** ```cpp template<> inline float tolerance<float>() { return 1e-5f; } template<> inline double tolerance<double>() { return 1e-11; } ``` - 根据标量类型自动选择阈值 2. **条件编译优化** ```cpp #ifdef USE_SSE // SIMD指令优化版本 #else // 通用实现 #endif ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值