W boost / mpl / assert.hpp widziałem coś takiego:
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;
};
Jeśli pierwszy ************
można potraktować jako wskaźniki struktury zawiodły, to P::************
naprawdę nie ma to dla mnie sensu. Czy to standardowy C ++?
P
z bardzo dużą pewnością, że nie będzie istnieć. (W C ++ 11 prawdopodobnie po prostu użyjeszstatic_assert(false)
zamiast tego, ale oczywiście Boost musi być przenośny do wersji wcześniejszej niż C ++ 11.)hunter2hunter2hunter2hunter2
tutajOdpowiedzi:
Celem tego kodu jest pomoc kompilatorowi w tworzeniu „widocznych” komunikatów o błędach.
W
static_assert
czasach wcześniejszych kompilowanie kodu z dużą ilością szablonów mogło z łatwością generować ~ 100 wierszy komunikatów o błędach nawet dla pojedynczego błędu, a 99% z tych wierszy jest często bez znaczenia.Sztuczka z 10 wskaźnikami jest przydatna, aby wskazać rzeczywisty błąd, na przykład:
BOOST_STATIC_ASSERT((std::is_same<T,U>));
Z gcc
T=void*
iU=char*
skompilowane za pomocą gcc daje ~ 10 linii błędów, ale możesz łatwo zobaczyć odpowiednią:error: no matching function for call to ‘assertion_failed(mpl_::failed************ std::is_same<void*, char*>::************)’
źródło
Jest to wskaźnik-do-wskaźnika-do -...- element członkowski typu
P
, gdzie element członkowski jest składnikiem danych typu wskaźnik-do-wskaźnika-do -...-failed
.W tym przypadku celem jest po prostu spowodowanie niepowodzenia kompilacji przez odwołanie się do członka
P
z bardzo dużym prawdopodobieństwem, że nie będzie on istniał. W C ++ 11 po prostu użyjeszstatic_assert
zamiast tego, ale oczywiście Boost musi być przenośny do dialektów sprzed C ++ 11.źródło
F P::*
jest „wskaźnikiem do elementuP
typuF
”.F P::**
jest „wskaźnikiem do wskaźnika do elementuP
typuF
”.Więcej
*
s dodaje więcej „wskaźnika do” z przodu.W tym przypadku
F
jest tofailed ************
np. „Wskaźnik do wskaźnika do… wskaźnika dofailed
”.źródło