C++ 自动类型推导
2018-05-14 本文已影响31人
district10
在弄 g2o 图优化的时候,需要设置一条边的置信度,大概如下:
auto e = new g2o::EdgeSE3ProjectXYZ();
e->setVertex(0, optimizer.vertex(idPoint(pMPt->mnId)));
e->setVertex(1, optimizer.vertex(idImu__(0)));
e->setMeasurement(...);
e->setInformation(Eigen::Matrix2d::Identity() * pF->confidence); // 这一行很蛋疼
e->setRobustKernel(newRobustKernel());
那行设置 information 矩阵蛋疼在于,这个 info mat 的维度取决于你的 error 的维度。
也就是说如果 error 是 double[2]
,你就 Eigen::Matrix2d
,如果 double[4]
,则是
Eigen::Matrix4d
。很多时候容易搞错。然后 Eigen 就报错一堆东西出来(可能还不告诉你哪一行挂了)。
回顾一下 g2o 边的定义:
class EdgeSE3ProjectXYZ : public BaseBinaryEdge<2, Vector2d, VertexSBAPointXYZ, VertexSE3Expmap> // ...
这里 2 是 error 的维度(可能“维度”有歧义,就这个意思你懂得);
Vector2d
是边的测量值类型
(通过edge->setMeamurement
设置进去);后面就是两个顶点类型,分别对应 vertex 0 和 vertex 1。
昨天写了一个类型推导,这样就能自己从 Edge 类型里面推导出 info mat 的类型,不用自己去改
Matrix2d
Matrix4d
这种东西。我查了挺久才找到我要的文档:http://en.cppreference.com/w/cpp/language/sfinae。
写好这个自动推导后,设置 info mat 只需要这样调用:
e->setInformation(utils::helpers::information(f->confidence, e));
有没有觉得用起来很爽?
这里是实现:
template <typename T> struct E
{
typedef typename T::InformationType InformationType;
};
template <typename T, typename W, typename = typename T::InformationType,
typename U = typename E<T>::InformationType>
U information(W c, const T *t)
{
return U::Identity() * c;
}