#define 实现快捷模板类实例在eigen::Maxtrix中的应用

欢迎关注更多精彩
关注我,学习常用算法与数据结构,一题多解,降维打击。

背景

在eigen库中,矩阵类原来的用法是 Matrix<Type, row, col>。
为了方便用户,库中还提供了用户常用的快捷类型,比如Matrix3d 代表Matrix<double, 3, 3>。
这种用法在eigen库里很多,产生的很多矩阵类型也记不住,特意去翻阅了eigen库源码,学习一下其实现原理。

顺便研究一下m(x, y)的实现原理。

原理

别名原理是利用define可以传递参数和##号来拼接出别名类型,事先在代码中生成using或typedef的语句来起别名。

括号原理是利用operator()(…) 后面的括号可以带多个参数,然后在程序中解析。

示例

模板类如下

template<typename T>
class M{
public:
	T v;
	
	T& operator()(int a, int b) {
		printf("%d %d\n", a,b);

		return v;
	}
};

期望效果

现在我想实现Mi=M<int>, Md=<double>, Mf=M<float>。

比较直接的做法是

using Mi = M<int>;typedef M<int> Mi;

参照eigen里的做法
把公共部分提取出来
先define 一个方法MT,然后根据类型去调用这个方法

// ##是连接符
#define MT(type, typesuffix) using M##typesuffix=M<type>;

// 下面调用3次类型初始化。
MT(int, i) // 生成 using Mi = M<int>;
MT(double, d) // 生成 using Md = M<double>;
MT(float, f) // 生成 using Mf = M<float>;

测试代码

void checkType(int a) {
	puts("int");
}


void checkType(double a) {
	puts("double");
}

void checkType(float a) {
	puts("float");
}

template<typename T>
class M{
public:
	T v;
	
	T& operator()(int a, int b) {
		printf("%d %d\n", a,b);

		return v;
	}
};

#define MT(type, typesuffix) using M##typesuffix=M<type>;

MT(int, i)
MT(double, d)
MT(float, f)


int main() {

	M<int> m1;
	checkType(m1.v);

	Md md;
	Mi mi;
	Mf mf;
	// 测试括号
	mi(1, 2) = 10;
	printf("%d\n", mi(1, 2));

	// 测试类型
	checkType(md.v);
	checkType(mi.v);
	checkType(mf.v);


	printf("ok\n");
	return 0;
}

测试效果

测试效果

源码解析


// matrix 类定义
template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
class Matrix
  : public PlainObjectBase<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
{
...
};

// 别名定义
#define EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, Size, SizeSuffix)   \
/** \ingroup matrixtypedefs */                                    \
typedef Matrix<Type, Size, Size> Matrix##SizeSuffix##TypeSuffix;  \ // 生成方阵形
/** \ingroup matrixtypedefs */                                    \
typedef Matrix<Type, Size, 1>    Vector##SizeSuffix##TypeSuffix;  \ // 生成列向量
/** \ingroup matrixtypedefs */                                    \
typedef Matrix<Type, 1, Size>    RowVector##SizeSuffix##TypeSuffix; // 生成行向量

... 这里省略了可变数组

// 生成3种不同规格的矩阵或向量
#define EIGEN_MAKE_TYPEDEFS_ALL_SIZES(Type, TypeSuffix) \
EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, 2, 2) \ 
EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, 3, 3) \
EIGEN_MAKE_TYPEDEFS(Type, TypeSuffix, 4, 4) \
...省略可变数组

EIGEN_MAKE_TYPEDEFS_ALL_SIZES(int,                  i) // 以方阵形为例,生成 typedef Matrix<int, 2, 2> Matrix2i; typedef Matrix<int, 3, 3> Matrix3i;typedef Matrix<int, 4, 4> Matrix4i;
EIGEN_MAKE_TYPEDEFS_ALL_SIZES(float,                f)
EIGEN_MAKE_TYPEDEFS_ALL_SIZES(double,               d)
EIGEN_MAKE_TYPEDEFS_ALL_SIZES(std::complex<float>,  cf)
EIGEN_MAKE_TYPEDEFS_ALL_SIZES(std::complex<double>, cd)

#undef EIGEN_MAKE_TYPEDEFS_ALL_SIZES
#undef EIGEN_MAKE_TYPEDEFS
#undef EIGEN_MAKE_FIXED_TYPEDEFS

常用类型总结

别名类型
Matrix3dMatrix<double, 3, 3>
Matrix3iMatrix<int, 3, 3>
Matrix3fMatrix<float, 3, 3>
Matrix2dMatrix<double, 2, 2>
Matrix2iMatrix<int, 2, 2>
Matrix2fMatrix<float, 2, 2>
Vector3dMatrix<double, 3, 1>
Vector3iMatrix<int, 3, 1>
Vector3fMatrix<float, 3, 1>

本人码农,希望通过自己的分享,让大家更容易学懂计算机知识。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值