typedef char в макросе

Я читаю библиотеку машинного обучения dlib, написанную на C ++. Я наткнулся на код в заголовочный файл который определяет кучу макросов. У меня трудности с пониманием следующего кода

#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]зачем это массив? Это законно?

0

Решение

Это статическое утверждение C ++ 03 или, по крайней мере, обходной путь, используемый для его моделирования.

Следующее определяет структуру, только если value верно, иначе тип не определен.

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]

Это определяет typedef на char массив размером 1, только если expression оценивает как истинное. Если выражение оценивается как ложное, то возникает ошибка времени компиляции и имя typedef является подсказкой об ошибке.

Обратите внимание, что есть несколько вариантов этого. Некоторые используют отрицательный или нулевой размер вместо ошибки компиляции, т.е. они определяют следующее:

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

Но на самом деле есть способ краткой формулировки этого (вы можете увидеть это в этом вопросе):

typedef char static_assert_something[expression ? 1 : -1];
3

Другие решения


По вопросам рекламы [email protected]