Was bedeutet P :: ************ in der Datei Boost assert.hpp?

80

In boost / mpl / assert.hpp habe ich so etwas gesehen:

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;
};

Wenn der erste ************als Zeiger der fehlgeschlagenen Struktur behandelt werden kann, P::************ergibt das für mich wirklich keinen Sinn. Ist das Standard C ++?

stoneyan
quelle
38
Pointerception ...
Jakub Arnold
5
@deviantfan Im Produktionscode? Du wärst überrascht. ;) Hier geht es jedoch darum, einen Kompilierungsfehler zu verursachen, indem versucht wird, Pmit sehr hoher Sicherheit auf ein Mitglied von zu verweisen, dass es nicht existiert. (In C ++ 11 würden Sie wahrscheinlich nur static_assert(false)stattdessen verwenden, aber natürlich muss Boost auf Pre-C ++ 11 portierbar sein.)
cdhowie
4
Randnotiz: Der 12-Ebenen-Zeiger hat wahrscheinlich etwas mit dem vom C-Standard geforderten Minimum zu tun.
TC
29
@ PaulDraper liest es tatsächlich hunter2hunter2hunter2hunter2hier
sehe
5
Zeiger auf einen Zeiger auf einen Zeiger auf einen Zeiger auf einen Zeiger auf einen Zeiger auf einen Zeiger auf einen Zeiger auf einen Zeiger auf einen Zeiger auf einen Zeiger auf einen Zeiger auf ein Mitglied vom Typ P
Kai

Antworten:

100

Der Zweck dieses Codes besteht darin, dem Compiler zu helfen, "sichtbare" Fehlermeldungen zu erzeugen.

In früheren static_assertZeiten konnte das Kompilieren eines vorlagenintensiven Codes leicht zu ~ 100 Zeilen Fehlermeldungen führen, selbst bei einem einzelnen Fehler, und 99% dieser Zeilen sind häufig bedeutungslos.

Der 10-Zeiger-Trick ist nützlich, um auf den tatsächlichen Fehler hinzuweisen, zum Beispiel:

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

Mit T=void*und U=char*kompiliert mit gcc werden ~ 10 Fehlerzeilen erzeugt, aber Sie können die relevante leicht sehen:

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

Es ist ein Zeiger-zu-Zeiger-zu -...- Mitglied vom Typ P, wobei das Mitglied ein Datenelement vom Typ Zeiger-zu-Zeiger-zu -...- ist failed.

In diesem Fall besteht das Ziel einfach darin, die Kompilierung zum Scheitern zu bringen, indem auf ein Mitglied Pmit einer sehr hohen Wahrscheinlichkeit verwiesen wird, dass es nicht existiert. In C ++ 11 würden Sie static_assertstattdessen nur verwenden , aber Boost muss natürlich für Dialekte vor C ++ 11 portierbar sein.

cdhowie
quelle
19

F P::*ist ein "Zeiger auf ein Mitglied Pvom Typ F".

F P::**ist ein "Zeiger auf Zeiger auf Mitglied Pvom Typ F".

Mehr *s fügt vorne mehr "Zeiger auf" hinzu.

In diesem Fall Fist failed ************dh "Zeiger auf Zeiger auf ... Zeiger auf failed".

TC
quelle