[Eigen中文文档] 断言

文档总目录

英文原文(Assertions)

断言

eigen_assert 默认定义为 eigen_plain_assert。我们使用 eigen_plain_assert 而不是 assert 来解决 GCC <= 4.3 的已知错误。基本上,eigen_plain_assert 就是断言。

重新定义断言

eigen_asserteigen_plain_assert两者都定义在Macros.h文件中。定义eigen_assert间接地提供了更改其行为的机会。如果您想执行其他操作(例如抛出异常),则可以重新定义此宏,并使用eigen_plain_assert返回其默认行为。以下代码告诉Eigen抛出一个std::runtime_error异常:

#include <stdexcept>
#undef eigen_assert
#define eigen_assert(x) \
  if (!(x)) { throw (std::runtime_error("Put your message here")); }
禁用断言

断言会消耗运行时间并且可以关闭。您可以通过在包含 Eigen 标头之前定义 EIGEN_NO_DEBUG 来抑制 eigen_assertEIGEN_NO_DEBUG 默认情况下未定义,除非定义了 NDEBUG

静态断言

静态断言直到 C++11 才标准化。然而,在 Eigen 库中,有很多条件可以而且应该在编译时检测到。例如,我们使用静态断言来防止下面的代码编译。

Matrix3d()  + Matrix4d();   // adding matrices of different sizes
Matrix4cd() * Vector3cd();  // invalid product known at compile time

静态断言在 StaticAssert.h 中定义。如果有原生的 static_assert,我们就使用它。否则,我们实现了一个断言宏,可以显示有限范围的消息。

可以轻松地提出没有消息的静态断言,例如:

#define STATIC_ASSERT(x) \
  switch(0) { case 0: case x:; }

然而,上面的例子显然无法说明断言失败的原因。因此,我们在命名空间 Eigen::internal 中定义一个结构体来处理可用的消息。

template<bool condition>
struct static_assertion {};
 
template<>
struct static_assertion<true>
{
  enum {
    YOU_TRIED_CALLING_A_VECTOR_METHOD_ON_A_MATRIX,
    YOU_MIXED_VECTORS_OF_DIFFERENT_SIZES,
    // see StaticAssert.h for all enums.
  };
};

然后,我们定义EIGEN_STATIC_ASSERT(CONDITION,MSG)以访问Eigen::internal::static_assertion<bool(CONDITION)>::MSG。如果条件计算为false,则编译器会显示许多消息,说明在static_assert<false>中不存在MSG。尽管如此,这不是我们感兴趣的。正如您所看到的,static_assert<true>的所有成员都是使用ALL_CAPS_AND_THEY_ARE_SHOUTING

警告:

使用此宏时,MSG 应该是 static_assertion<true> 的成员,否则静态断言总是失败。目前,它只能在函数范围内使用。

派生静态断言

还有其他从 EIGEN_STATIC_ASSERT 派生的宏来增强可读性。他们的名字是不言自明的。

  • EIGEN_STATIC_ASSERT_FIXED_SIZE(TYPE) 如果 TYPE 是固定大小则通过。
  • EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(TYPE) 如果 TYPE 是动态大小则通过。
  • EIGEN_STATIC_ASSERT_LVALUE(Derived) 如果 Derived 是只读的,则失败。
  • EIGEN_STATIC_ASSERT_ARRAYXPR(Derived) 如果 Derived 是数组表达式,则通过。
  • EIGEN_STATIC_ASSERT_SAME_XPR_KIND(Derived1, Derived2) 如果两个表达式是数组和矩阵,则失败。

由于 Eigen 同时处理固定大小和动态大小表达式,因此某些条件无法在编译时明确确定。我们将它们分为严格断言和宽容断言。

严格断言

如果条件不满足,这些断言就会失败。例如,MatrixXd 可能不是向量,因此它会失败 EIGEN_STATIC_ASSERT_VECTOR_ONLY

  • EIGEN_STATIC_ASSERT_VECTOR_ONLY(TYPE) 如果 TYPE 必须是向量类型,则通过。
  • EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(TYPE, SIZE) 如果 TYPE 必须是给定大小的向量,则通过。
  • EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(TYPE, ROWS, COLS) 如果 TYPE 必须是具有给定行和列的矩阵,则通过。
宽容断言

如果无法满足条件,这些断言就会失败。例如,MatrixXdMatrix4d 可能具有相同的大小,因此它们传递 EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE

  • EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(TYPE0,TYPE1) 如果两个向量表达式类型必须具有不同的大小,则失败。
  • EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(TYPE0,TYPE1) 如果两个矩阵表达式类型必须具有不同的大小,则失败。
  • EIGEN_STATIC_ASSERT_SIZE_1x1(TYPE) 如果 TYPE 不能是 1x1 表达式,则失败。

有关它们抛出的消息等详细信息,请参阅 StaticAssert.h

禁用静态断言

如果定义了 EIGEN_NO_STATIC_ASSERT,静态断言将变成 eigen_assert,工作方式如下:

#define EIGEN_STATIC_ASSERT(CONDITION,MSG) eigen_assert((CONDITION) && #MSG);

这节省了编译时间,但消耗了更多运行时间。默认情况下,EIGEN_NO_STATIC_ASSERT 未定义。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

万俟淋曦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值