consideri questo frammento di codice, che utilizza il linguaggio comune avente un modello di funzione costrutto un'istanza di una classe template specializzato su un tipo dedotta, come visto con std::make_unique
e std::make_tuple
, ad esempio:È un riferimento universale? Std :: forward ha senso qui?
template <typename T>
struct foo
{
std::decay_t<T> v_;
foo(T&& v) : v_(std::forward<T>(v)) {}
};
template <typename U>
foo<U> make_foo(U&& v)
{
return { std::forward<U>(v) };
}
Nel contesto dei "riferimenti universali" di Scott Meyers, l'argomento a make_foo
è un riferimento universale perché il suo tipo è dove U
è dedotto. L'argomento del costruttore di foo
non è un riferimento universale perché sebbene il suo tipo sia T&&
, è (in generale) non dedotto.
Ma nel caso in cui il costruttore di foo
è chiamato da make_foo
, si mi sembra che potrebbe dare un senso pensare al argomento al costruttore di foo
come un riferimento universale, perché T
è stato dedotta dal modello di funzione make_foo
. Le stesse regole di compressione di riferimento verranno applicate in modo che il tipo di v
sia lo stesso in entrambe le funzioni. In questo caso, si può affermare che sia T
e U
siano stati dedotti.
Quindi la mia domanda è duplice:
- Ha senso pensare al argomento al costruttore di
foo
come un riferimento universale nei limitati casi in cuiT
è stata dedotta all'interno di un universale contesto di riferimento dal chiamante, come nel mio esempio? - Nel mio esempio, sono entrambi sensati gli usi di
std::forward
?
In alternativa, utilizzare 'std :: mossa (v)' all'interno del costruttore originale – TemplateRex
@TemplateRex: I don' Voglio chiamarlo "alternativa", poiché non è chiaramente quello che l'OP voleva (da allora il produttore non avrebbe avuto senso ad accettare i riferimenti lvalue). –
Il costruttore di 'foo' accetta un riferimento lvalue. L'utilizzo di 'std :: forward ' potrebbe avere senso in questo caso. –
nosid