Warum kann der Compiler den Template-Parameter für std::forward
nicht herleiten?
Ich meine:
%Vor% Ich weiß, dass dies eine Designauswahl ist (aufgrund der std::remove_reference
in der Definition von std::forward
), um zu vermeiden, dass der Benutzer den Typ angibt. Was ich nicht bekommen kann, ist: warum die Art und Weise, wie es implementiert wird, um eine Deduktion zu verhindern? Warum der Compiler nicht nur den Template-Parameter forward
als Arg
ableitet.
std::forward
wird wie folgt deklariert:
typename std::remove_reference<T>::type
ist ein nicht-abgeleiteter Kontext . Der Compiler kann nicht wissen, welche T
abgeleitet werden soll, weil er die semantische Verbindung zwischen dem Elementtyp type
und einem gegebenen T
nicht versteht. Es müsste alle Typen durchsuchen, um eine Übereinstimmung zu finden und Kollisionen irgendwie zu disambiguieren. Dies ist unangemessen, so dass es der Standard nicht erlaubt.
Der Grund, dass Sie für forward
einen Designtyp angeben müssen, ist, was mit a
in der Funktion geschieht:
Da a
immer ist, gibt es nicht genug Informationen in a
selbst, um feststellen zu können, ob es als Lvalue oder Rvalue übergeben wurde. Diese Informationen sind nur über den Typ Arg
verfügbar, der entweder X
oder X&
ist. Ohne diese zusätzlichen Informationen ist es unmöglich zu wissen, ob oder jetzt a
als lvalue oder rvalue weitergeleitet werden muss. Deshalb müssen Sie Folgendes angeben:
Ab C ++ 11 Standard:
14.8.2.5 Ableiten von Vorlagenargumenten von einem Typ
Die nicht abgeleiteten Kontexte sind:
- Der Nested-Name-Specifier eines Typs, der mit einer qualifizierten ID angegeben wurde
- Der Ausdruck eines Deklarationstyp-Spezifizierers.
- Ein nicht typisiertes Vorlagenargument oder eine Array-Grenze, in der a Unterausdruck verweist auf einen Vorlagenparameter.
- Ein Vorlagenparameter, der im Parametertyp einer Funktion verwendet wird Parameter mit einem Standardargument, das im Aufruf verwendet wird Für welches Argument wird ein Abzug vorgenommen.
usw. ...
std::forward
wird wie folgt deklariert:
template<typename _Tp>
constexpr _Tp&& forward(typename std::remove_reference<_Tp>::type& __t) noexcept
Nach dem ersten Satz oben:
typename std::remove_reference<_Tp>::type
ist nicht abgeleiteter Kontext.
Tags und Links c++ c++11 perfect-forwarding