std::remove_reference erklären?
Sah ich mögliche Implementierungen für std::remove_reference
wie unten
template< class T > struct remove_reference {typedef T type;};
template< class T > struct remove_reference<T&> {typedef T type;};
template< class T > struct remove_reference<T&&> {typedef T type;};
Warum ist es, dass es Spezialisierungen für lvalue
und rvalue reference
? Nicht die Allgemeine Schablone selbst ausreichend sein, und den Verweis entfernen? Ich bin verwirrt, weil hier in der T&
oder T&&
Spezialisierung, wenn ich versuche, mit ::type
sollte ich noch bekommen T&
oder T&&
bzw. rechts?
Könnten Sie erklären, wie, warum werfen wir zu remove_reference<t>::type&&
im Zug? (ist es denn, dass der parameter benannt ist, so wird er behandelt, wie ein lvalue innerhalb der verschieben-Funktion?).
Außerdem konnten Sie zeigen einen Weg, wobei ich herausfinden kann und drucken, was das geben wird? für e.g, wenn seine rvalue
Typ int
dann sollte ich in der Lage zu drucken, die int&&
übergeben wurde? (Ich habe mit std::is_same
zu überprüfen, sondern manuell.)
Vielen Dank für Ihre Zeit.
- Dies ist eine SEHR gute Frage!
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn nur die primäre Vorlage existiert, dann tut:
Geben würde Sie:
Haben und tun:
Geben würde Sie:
Ist nicht, was Sie wollen. Die Spezialisierungen für lvalue rvalue Referenzen und Verweise ermöglichen das abstreifen des
&
und die&&
bzw. aus dem type-argument übergeben Sie.Zum Beispiel, wenn Sie tun:
Art
int&&
wird mit dem Muster gemäß derT&&
Spezialisierung, mitT
wirdint
. Seit der Spezialisierung definiert den Typ aliastype
zuT
(in diesem Fallint
), in:Geben Sie
int
.Das ist, weil, wenn
move()
wurden wie folgt definiert:Dann die return-Typ wird
X&
wenn das argument vonmove()
ist ein lvalue des TypsX
(das ist, wie die so genannten "universal-Verweise"). Wir wollen sicherstellen, dass der Rückgabetyp ist immer eine rvalue-Referenz.Zweck der
move()
ist, um Ihnen wieder ein rvalue, egal, was Sie übergeben, input. Da ein Funktionsaufruf für eine Funktion, deren Rückgabetyp ist eine rvalue-Referenz ist ein rvalue, wollen wir wirklichmove()
um immer wieder eine rvalue-Referenz.Das ist, warum wir tun
remove_reference<T>::type&&
, weil anfügen&&
zu einem nicht-Referenz-Typ ist immer gewährleistet, ergeben eine rvalue-Referenz-Typ.Ich bin mir nicht sicher, was du meinst mit "print" hier. Es gibt keinen portablen Weg, den ich kenne, der Umwandlung der Namen von einem Typ zu einem string (egal wie man zu erhalten, die Art).
Wenn Ihr Ziel ist, um sicherzustellen, dass ein rvalue übergeben wurde, auf der anderen Seite, könnte man eine statische Behauptung etwa so:
Die stützt sich auf die Tatsache, dass, wenn ein lvalue des Typs
X
übergeben wird,T
abgeleitet werdenX&
.Könnten Sie auch einen gleichwertigen SFINAE-Einschränkung, wenn Sie nur wollen, um zu produzieren eine substitution failure:
T&&
? Allgemeine Vorlage behandeln können dieses Recht?remove_reference<int&&>::type
geben würde, Sie zurückint&&
T&&
bekommen wirT&&
für::type
Recht?T
, weil die Spezialisierung der dem Muster entsprichtT&&
, so dass, wenn Sie passieren (sagen)int&&
und passen Sie es mitT&&
IhreT
muss nurint
T&&
Spezialisierung derT
in die typedef ist immer nochT&&
. aber ich bin falsch.es istT
. Vielen Dank:-)typename = std::enable_if_t<...>
stattstd::is_reference<T>::value
gilt für rvalues zu?lvalue
undrvalue
.Wenn Sie behandeln einige Typ als template-parameter compiler sucht für die meisten "spezialisierten" Spezialisierung. Wenn du an eine int&& zu dieser Vorlage, compiler verwenden
remove_reference<T&&>
version. Allgemeine Spezialisierung nicht geben Ihnen, was Sie wollen - wenn Sie passint&&
Allgemeinen specialiation, Typint&&
Wenn Sie drucken möchten geben, verwenden Sie
typeid(some_type).name()
c++filt -t
zu unmangle gcctypeid()::name()
Ausgabe. Zum Beispielc++filt -t FRSt8ios_baseS0_E
zurückstd::ios_base& (std::ios_base&)
- das ist der Typ der Funktionstd::boolalpha
.