2014-11-12 8 views
10

Ich war die Umsetzung des clamp im Boost-Überprüfung:Was ist der Punkt von "boost :: mpl :: identity <T> :: type" hier?

template<typename T, typename Pred> 
    T const & clamp (T const& val, 
    typename boost::mpl::identity<T>::type const & lo, 
    typename boost::mpl::identity<T>::type const & hi, Pred p) 
    { 
// assert (!p (hi, lo)); // Can't assert p (lo, hi) b/c they might be equal 
    return p (val, lo) ? lo : p (hi, val) ? hi : val; 
    } 

Wenn ich die Dokumentation nachschlagen, identity das Template-Argument unverändert zurückgegeben.

Die Identität Metafunktion. Gibt X unverändert zurück.

Also, was ist der Sinn der Verwendung hier?

Ist nicht typename boost::mpl::identity<T>::type entspricht T?

+6

deaktiviert Typ Abzug auf diese Parameter –

+0

so zieht es "T" rein basierend auf dem ersten Parameter? aaaah ... thx –

+0

ja, genau wie du gesagt hast –

Antwort

13

Ein verschachtelter Name-Spezifizierer erstellt einen nicht-abgeleiteten Kontext. Daher versuchen, ein Compiler nicht Typen T wie erklärt auf der Grundlage der zweiten und dritten Parameter abzuleiten:

typename boost::mpl::identity<T>::type const & 

Typ T abgeleitet nur von der Art des ersten Arguments basieren wird, und dann verwendet, um die Typen zu instanziiert der Restparameter. Die Verwendung des Typs identity ist ein häufiger Trick, um die Ableitung von Schablonenargumenttypen für bestimmte Parameter zu verhindern, die andernfalls zu einem mehrdeutigen Aufruffehler führen würden, falls sich die Argumenttypen unterscheiden, aber denselben Schablonenparameter verwenden. Es kann auch manchmal gewünscht sein, einen Compiler nicht automatisch auf den Typ schließen zu lassen und einen Aufrufer dazu zwingen, es selbst zu tun.

+0

Gibt es noch andere weg, um das gleiche Ergebnis zu erzielen? (Außerhalb von ich denke, eine andere Funktion zu schreiben und die 'lo' und' hi') – Barry

+1

@Barry ohne Zweifel, weil es ähnliche Möglichkeiten, nicht nachvollziehbaren Kontext zu erstellen. Allerdings werden nur wenige so elegant und idiomatisch sein. Also, warum würdest du es anders wollen? (Wenn Sie MPL nicht mögen, schreiben Sie einfach die Meta-Funktion 'identity' selbst. Es ist alles ~ 6 Zeilen Code) – sehe

+4

+1 Ein Nitpick: Sie möchten vielleicht erwähnen, dass die Verwendung des geschachtelten' :: type' in a Der nicht-abgeleitete Kontext erlaubt implizite Konvertierungen von 'hi' und' lo', die bei der Argumentableitung nicht berücksichtigt werden. Die Verwendung solcher gemischten Parametertypen wäre hier die Hauptanwendung. – TemplateRex

Verwandte Themen