2016-05-24 7 views
6

Gemäß this link hilft uns der Vorlagenargumentabzug, der für std::forward und std::remove_reference nicht zulässig ist, uns dies zu erreichen. Aber wie verhindert die Verwendung von remove_reference hier den Abzug von Vorlagen? DieseWie remove_reference Schablonenargumentabzüge deaktivieren?

template <class S> 
S&& forward(typename std::remove_reference<S>::type& t) noexcept 
{ 
    return static_cast<S&&>(t); 
} 

Antwort

6

S im Ausdruck typename std::remove_reference<S>::type ist ein nicht abgeleitete Kontext (insbesondere weil S erscheint in dem verschachtelten-name-specifier ein Typ angegeben mit einem qualifizierte-ID). Nicht-abgeleitete Kontexte sind, wie der Name sagt, Kontexte, in denen das Template-Argument nicht abgeleitet werden kann.

Dieser Fall bietet ein einfaches Beispiel, um zu verstehen, warum. Sprich ich hatte:

int i; 
forward(i); 

Was wäre S? Es könnte int, int& oder int&& sein - alle diese Typen würden den korrekten Argumenttyp für die Funktion ergeben. Es ist einfach unmöglich für den Compiler zu bestimmen welcheS Sie wirklich hier meinen - also es nicht versucht. Es ist nicht ableitbar, so dass Sie sich ausdrücklich vor, welche S Sie nach:

forward<int&>(i); // oh, got it, you meant S=int& 
+0

"Ich könnte einen völlig unzusammenhängenden Typ' Foo' haben, auf den ich mich spezialisiert habe "remove_reference ', um den Typ 'int' zu haben." Das ist technisch UB :) –

+0

@ T.C. Ok, ich werde diesen Teil entfernen. Ich möchte keine schlechten Ideen verbreiten! – Barry

+0

Ich empfehle, "weil S ist der Nested-Name-Specifier" zu etwas wie "weil S erscheint im Nested-Name-Specifier" umformulieren –

-4

ist, wie remove_reference implementiert:

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

Aber warum denn dies wird sichergestellt sein, dass Template-Argument nicht abgeleitet werden sollte? – Kapil

+0

Die Frage ist nicht "Wie wird' remove_reference' implementiert? " – Barry

+0

@Barry Mit der Definition von 'remove_reference' können Sie sehen, wie die Ableitung von Vorlagenargumenten deaktiviert wird. Dies ist die genaueste Antwort. –