Pourquoi le compilateur n'est pas capable de déduire le paramètre de modèle pour Je veux dire: p> std :: Transférer code>?
#include <memory>
#include <iostream>
struct X{};
struct A{
A( const X& ) { std::cout << "cpy ctor\n"; }
A( X&& ) { std::cout << "move ctor\n"; }
};
X foo() { return {}; }
template<typename T,typename Arg>
T* factory( Arg&& a )
{
return new T(std::forward(a));
// ----------^^^^^^^^^^^^^^^ error: can't deduce template parameter
}
int main()
{
factory<A>(foo());
}
3 Réponses :
std :: Transférer code> est déclaré comme:
typename std :: supprimer_reference
t code> doit être déduit car il ne comprend pas la connexion sémantique entre le type de membre code> type code> et un
t code donné >. Il aurait besoin de rechercher tous les types pour trouver un match et être capable d'en quelque sorte des collisions de désambiguë. Ceci est déraisonnable, la norme ne le permet pas. P> p>
Oui, c'est ce que je demandais. Je pense que lire Ce fera le reste.
La raison pour laquelle vous devez spécifier un type pour Étant donné que Transférer code>, par conception, c'est ce qui arrive à
a code> à l'intérieur de la fonction:
A code> est toujours em> un lvalue, il n'y a pas assez d'informations dans
A code> pour pouvoir déterminer si elle a été transmise en tant que lvalue ou rvalue. que em> les informations sont uniquement disponibles via le type
arg code>, qui sera soit
x code> ou
x & code>. Sans cette information de type supplémentaire, il est impossible de savoir si ou maintenant
A code> doit être envoyé comme un lvalue ou une rvalue ... C'est pourquoi vous devez le fournir: P>
return new T(std::forward<Arg>(a));
}
Eh bien, je pensais que OP posait une question légèrement différente. Laissera cela ici quand même.
Oui, mon mauvais. Ce n'était pas très clair de la question. J'espère que la modification aide à comprendre ce qui était mon problème.
de C ++ 11 Standard: P>
14.8.2.5 Arguments de modèle de déduction à partir d'un type p>
Les contextes non déduits sont: p>
- le spécificateur de nom imbriqué d'un type spécifié à l'aide d'un identifiant qualifié p>
- L'expression d'un spécificateur déclencheur. p>
- un argument de modèle de type de type ou une matrice liée dans laquelle a La subexpression fait référence à un paramètre de modèle. p>
- un paramètre de modèle utilisé dans le type de paramètre d'une fonction paramètre qui a un argument par défaut qui est utilisé dans l'appel pour quelle déduction de l'argument est en cours. P>
etc ... p> blockQuote>
std :: avance code> est déclaré comme ceci: p>
modèle
Constexpr _TP && Transférer (Typename STD :: Remove_Reference <_TP> :: Type & __T) Noexcept Code> P> Selon la première phrase ci-dessus:
typename std :: supprimer_reference <_tp> :: Type code> est un contexte non déduit. p>
Pouvez-vous clarifier la question? Demandez-vous pourquoi la conception a été choisie pour prévenir la déduction de l'argument ou pourquoi la façon dont elle est mise en œuvre fonctionne pour prévenir la déduction?
Le point de spécifier le type manuellement est de sorte que
transfert code> peut décider s'il doit être
déplacer code>
A code> ou non. Déduction de l'argument de modèle vous permet de déterminer le type de
A code> mais pas si cela devrait être déplacé ou non.
@Angew le second.