2014-11-19 12 views
80

In boost/mpl/assert.hpp, ho visto qualcosa di simile:Che cosa significa P :: ************ nel file 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; 
}; 

Se il primo ************ possono essere trattati come puntatori di struct fallito, il P::************ realtà non ha alcun senso per me. È questo standard C++?

+1

Sì. È un puntatore a più livelli per puntare al membro di 'P'. –

+1

(Tali puntatori nidificati esistono?: /) – deviantfan

+38

Pointerception ... –

risposta

45

È un membro da puntatore a puntatore a -...- di tipo P, in cui il membro è un membro dati di tipo pointer-to-pointer-to -...- failed.

In questo caso l'obiettivo è semplicemente quello di causare la compilazione non riuscendo facendo riferimento a un membro di P con un grado molto alto di probabilità che non esisterà. In C++ 11 dovresti semplicemente usare static_assert invece, ma ovviamente Boost deve essere portatile per i dialetti pre-C++ 11.

19

F P::* è un "puntatore a membro di P di tipo F".

F P::** è un "puntatore a puntatore a membro di P di tipo F".

Altro * s aggiunge più "puntatore a" davanti.

In questo caso, F è failed ************, cioè "puntatore a puntatore a ... puntatore su failed".

+3

Molto semplice ma al punto :) – ha9u63ar

100

Il punto di questo codice è di aiutare il compilatore a produrre messaggi di errore "visibili".

In epoca pre static_assert, la compilazione di un codice modello pesante poteva facilmente produrre ~ 100 righe di messaggi di errore anche per un singolo errore, e il 99% di quelle linee sono spesso prive di significato.

Il 10 puntatori trucco è utile sottolineare l'errore effettivo, ad esempio:

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

Con T=void* e U=char* compilato con gcc produce ~ linee 10 di errore, ma si può facilmente vedere il relativo uno:

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