0

我正在阅读用 C++ 编写的机器学习库 dlib。我在一个定义了一堆宏的头文件中遇到了一个代码。我很难理解以下代码

#ifndef BOOST_JOIN
#define BOOST_JOIN( X, Y ) BOOST_DO_JOIN( X, Y )
#define BOOST_DO_JOIN( X, Y ) BOOST_DO_JOIN2(X,Y)
#define BOOST_DO_JOIN2( X, Y ) X##Y
#endif
//  a bunch of other code

namespace dlib
{
template <bool value> struct compile_time_assert;
template <> struct compile_time_assert<true> { enum {value=1};  };
// a bunch of other definitions
}

#define COMPILE_TIME_ASSERT(expression) \
    DLIB_NO_WARN_UNUSED typedef char BOOST_JOIN(DLIB_CTA, __LINE__)[::dlib::compile_time_assert<(bool)(expression)>::value] 

我不明白的是

  1. 上面代码的最后一行是做什么的?

  2. typedef char这里太奇怪了,我完全不明白。

  3. 替换BOOST_JOIN后就变成DLIB_CTA__LINE__[1]了,为什么是数组呢?合法吗?
4

1 回答 1

3

这是一个 C++03 静态断言,或者至少是用于模拟它的解决方法。

以下仅在value为 true 时定义结构,否则未定义类型。

template <bool value> struct compile_time_assert;
template <> struct compile_time_assert<true> { enum {value=1};  };

这意味着compile_time_assert<true>::value完全正确,但由于未定义,因此compile_time_assert<false>::value是编译错误。compile_time_assert<false>

现在,断言的核心:

DLIB_NO_WARN_UNUSED typedef char BOOST_JOIN(DLIB_CTA, __LINE__) ::dlib::compile_time_assert<(bool)(expression)>::value]

这在大小为 1 的数组上定义了 typedef char,仅当expression计算结果为 true 时。如果表达式的计算结果为 false,则存在编译时错误,并且 typedef 的名称是有关该错误的提示。

请注意,这有一些变体。有些使用负数或空大小而不是编译错误,即它们定义以下内容:

template <> struct compile_time_assert<false> { enum { value = -1 };  };

但实际上有一种简洁的表述方式(你可以在这个问题中看到它):

typedef char static_assert_something[expression ? 1 : -1];
于 2015-04-08T18:44:52.647 回答