Что означает P:: ************ в файле Boost assert.hpp?
В boost/mpl/assert.hpp я увидел что-то вроде этого:
template<class Pred>
struct eval_assert {
typedef typename extract_assert_pred<Pred>::type P;
typedef typename P::type p_type;
typedef typename ::boost::mpl::if_c<p_type::value,
AUX778076_ASSERT_ARG(assert<false>),
failed ************ P::************
>::type type;
};
Если первый ************
можно рассматривать как указатели struct failed, P::************
действительно не имеет для меня никакого смысла. Является ли этот стандартный С++?
Ответы
Ответ 1
Точка этого кода должна помочь компилятору вывести "видимые" сообщения об ошибках.
В эпоху pre static_assert
компиляция тяжелого кода с шаблоном может легко создавать ~ 100 строк сообщений об ошибках даже для одной ошибки, а 99% этих строк часто бессмысленны.
Трюк 10 указателей полезен для указания фактической ошибки, например:
BOOST_STATIC_ASSERT((std::is_same<T,U>));
С T=void*
и U=char*
, скомпилированным с gcc, выдает ~ 10 строк ошибок, но вы можете легко увидеть соответствующий:
error: no matching function for call to ‘assertion_failed(mpl_::failed************ std::is_same<void*, char*>::************)’
Ответ 2
Это указатель на указатель-на -...- член типа P
, где член является членом данных типа pointer-to-pointer-to -...- failed
.
В этом случае целью является просто заставить компиляцию сбой, обратившись к члену P
с очень высокой степенью вероятности, что он не будет существовать. В С++ 11 вы просто используете static_assert
, но, конечно, Boost должен быть переносимым на диалекты pre-С++ 11.
Ответ 3
F P::*
является "указателем на член P
типа F
".
F P::**
является "указателем на указатель на элемент P
типа F
".
Дополнительно *
добавляет больше "указатель" на передний план.
В этом случае F
есть failed ************
, то есть "указатель на указатель на... указатель на failed
".