2014-11-19 8 views
80

W boost/mpl/assert.hpp, widziałem coś takiego:Co oznacza P :: ************ w pliku Boost 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; 
}; 

Jeśli pierwszy ************ można traktować jako wskaźniki od struktury nie powiodła, P::************ naprawdę nie ma sensu do mnie. Czy to jest standardowe C++?

+1

Tak. Jest to wielopoziomowy wskaźnik do wskaźnika do elementu 'P'. –

+1

(Takie zagnieżdżone wskaźniki istnieją?: /) – deviantfan

+38

Pointerception ... –

Odpowiedz

45

Jest to element wskaźnika do wskaźnika-do -...- typu P, w którym element członkowski jest elementem danych typu wskaźnik do wskaźnika-do -...- failed.

W tym przypadku celem jest po prostu spowodowanie niepowodzenia kompilacji przez odniesienie się do członka z P z bardzo wysokim prawdopodobieństwem, że nie istnieje. W C++ 11 zamiast tego używałbyś po prostu static_assert, ale oczywiście Boost musi być przenośny dla pre-C++ 11 dialektów.

19

to "wskaźnik do elementu P typu F".

F P::** to "wskaźnik do wskaźnika do elementu P typu F".

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

W tym przypadku F to failed ************, tj. "Wskaźnik do wskaźnika na ... wskaźnik do failed".

+3

Bardzo proste, ale na temat :) – ha9u63ar

100

Celem tego kodu jest pomoc kompilatorowi w generowaniu "widocznych" komunikatów o błędach.

W erze pre-static_assert, skompilowanie kodu obciążającego szablon może z łatwością wygenerować ~ 100 linii komunikatów o błędach nawet w przypadku pojedynczego błędu, a 99% z tych linii często nie ma znaczenia.

Sztuką 10 wskazówek jest przydatna wskazać rzeczywisty błąd, na przykład:

BOOST_STATIC_ASSERT((std::is_same<T,U>)); 

Z T=void* i U=char* skompilowane z gcc produkuje ~ linii 10 o błędach, ale można łatwo zobaczyć odpowiedni jeden:

error: no matching function for call to ‘assertion_failed(mpl_::failed************ std::is_same<void*, char*>::************)’