Understanding std :: forward

8

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.

    
Paolo M 25.08.2015, 13:08
quelle

3 Antworten

12

std::forward wird wie folgt deklariert:

%Vor%

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.

    
TartanLlama 25.08.2015, 13:16
quelle
6

Der Grund, dass Sie für forward einen Designtyp angeben müssen, ist, was mit a in der Funktion geschieht:

%Vor%

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:

%Vor%     
Barry 25.08.2015 13:18
quelle
0

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.

    
Elohim Meth 25.08.2015 13:48
quelle

Tags und Links