Lvalue pour valider la liaison de référence
Le compilateur garde de se plaindre, je suis en train de lier une lvalue de référence rvalue, mais je ne vois pas comment. Je suis novice en C++11, la sémantique de déplacement, etc., donc, s'il vous plaît garder avec moi.
J'ai cette fonction:
template <typename Key, typename Value, typename HashFunction, typename Equals>
Value& FastHash<Key, Value, HashFunction, Equals>::operator[](Key&& key)
{
// Some code here...
Insert(key, Value()); //Compiler error here
// More code here.
}
qui appelle cette méthode:
template <typename Key, typename Value, typename HashFunction, typename Equals>
void FastHash<Key, Value, HashFunction, Equals>::Insert(Key&& key, Value&& value)
{
//...
}
Je continue à recevoir des erreurs comme suit:
cannot convert argument 1 from 'std::string' to 'std::string &&'
sur l'Insert (). N'est-ce pas key
définie comme une rvalue dans la surcharge de l'opérateur? Pourquoi est-il d'être réinterprétée comme une lvalue?
Grâce.
source d'informationauteur Kristian D'Amato
Vous devez vous connecter pour publier un commentaire.
key
ici estKey&& key
- c'est une lvalue! Il a un nom, et vous pouvez prendre à son adresse. C'est juste que le type de qui lvalue est "référence rvalue àKey
".Vous avez besoin pour passer une rvalue, et pour cela vous avez besoin d'utiliser
std::move
:Je peux voir pourquoi c'est contre-intuitif! Mais une fois que vous distinguer et de référence rvalue (qui est une référence lié à une rvalue) et d'une véritable rvalue, il devient plus clair.
Edit: le vrai problème ici est d'utiliser les références rvalue. Il est logique de les utiliser dans un modèle de fonction lorsque le type de l'argument est déduit, car cela permet à l'argument de se lier soit à une lvalue de référence ou référence rvalue, en raison de l'effondrement de référence des règles. Voir cet article et la vidéo pour comprendre pourquoi: http://isocpp.org/blog/2012/11/universal-references-in-c11-scott-meyers
Toutefois, dans ce cas, le type de Clé n'est pas déduite lorsque la fonction est appelée, comme il a déjà été déterminé par la classe lorsque vous instancié
FastHash<std::string, ... >
. Ainsi, vous êtes vraiment à prescrire l'utilisation de références rvalue, et donc à l'aide destd::move
corrige le code.Je voudrais modifier votre code pour que les paramètres sont à prendre en valeur:
Ne vous inquiétez pas trop à propos des copies supplémentaires en raison de l'utilisation de la valeur des arguments - ci sont fréquemment optimisé par le compilateur.