2016-05-24 29 views

risposta

6

S nell'espressione typename std::remove_reference<S>::type è un non-dedotta contesto (proprio perché S appare nella nested-nome-specificatore di un tipo specificato utilizzando un ID qualificata). I contesti non dedotti sono, come suggerisce il nome, contesti in cui l'argomento del modello non può essere dedotto.

Questo caso fornisce un semplice esempio per capire perché. Dire che ho:

int i; 
forward(i); 

Che cosa sarebbe S essere? Potrebbe essere int, int& o int&& - tutti questi tipi restituirebbero il tipo di argomento corretto per la funzione. È semplicemente impossibile per il compilatore determinare qualeS si intende veramente qui - quindi non prova. E 'non deducibili, quindi bisogna prevedere esplicitamente che S cercavi:

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

"Potrei avere un tipo completamente diverso' Foo' per il quale sono specializzato 'remove_reference ' per avere il tipo 'int'." Questo è tecnicamente UB :) –

+0

@ T.C. Ok, rimuoverò quella parte. Non vorrei diffondere cattive idee! – Barry

+0

Raccomando di riformulare "perché S è lo specificatore del nome nidificato" per qualcosa di simile "perché S appare nello specificatore nome-nidificato" –

-4

Questo è il modo in Remove_Reference viene implementato:

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

Ma perché a causa di questo sarà garantito che l'argomento modello non dovrebbe essere dedotto? – Kapil

+0

La domanda non è "come viene implementato' remove_reference'? " – Barry

+0

@Barry data la definizione di 'remove_reference', puoi vedere come disabilita la deduzione degli argomenti del template. Questa è la risposta più accurata. –