Co oznacza P :: ************ w pliku Boost assert.hpp?

80

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 ++?

kamienny
źródło
38
Pointerception ...
Jakub Arnold
5
@deviantfan W kodzie produkcyjnym? Byłbyś zaskoczony. ;) Ale chodzi o to, aby spowodować niepowodzenie kompilacji, próbując odwołać się do członka Pz bardzo dużą pewnością, że nie będzie istnieć. (W C ++ 11 prawdopodobnie po prostu użyjesz static_assert(false)zamiast tego, ale oczywiście Boost musi być przenośny do wersji wcześniejszej niż C ++ 11.)
cdhowie
4
Uwaga dodatkowa: 12-poziomowy wskaźnik prawdopodobnie ma coś wspólnego z minimum wymaganym przez standard C.
TC,
29
@PaulDraper to faktycznie czytanie hunter2hunter2hunter2hunter2tutaj
sehe
5
wskaźnik do wskaźnika do wskaźnika do wskaźnika do wskaźnika do wskaźnika do wskaźnika do wskaźnika do wskaźnika do wskaźnika do wskaźnika do wskaźnika do elementu członkowskiego typu P
Kai

Odpowiedzi:

100

Celem tego kodu jest pomoc kompilatorowi w tworzeniu „widocznych” komunikatów o błędach.

W static_assertczasach 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*i U=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*>::************)’
sbabbi
źródło
45

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 Pz bardzo dużym prawdopodobieństwem, że nie będzie on istniał. W C ++ 11 po prostu użyjesz static_assertzamiast tego, ale oczywiście Boost musi być przenośny do dialektów sprzed C ++ 11.

cdhowie
źródło
19

F P::*jest „wskaźnikiem do elementu Ptypu F”.

F P::**jest „wskaźnikiem do wskaźnika do elementu Ptypu F”.

Więcej *s dodaje więcej „wskaźnika do” z przodu.

W tym przypadku Fjest to failed ************np. „Wskaźnik do wskaźnika do… wskaźnika do failed”.

TC
źródło