Essayer d'utiliser des fictions modélisées pour échanger deux chaînes

9
#include<iostream>
#include<string>

template <typename T>
void swap(T a , T b)
{
  T temp = a;
  a = b;
  b = temp;
}

template <typename T1>
void swap1(T1 a , T1 b)
{
  T1 temp = a;
  a = b;
  b = temp;
}

int main()
{
  int a = 10 , b = 20;
  std::string first = "hi" , last = "Bye";

  swap(a,b);
  swap(first, last);   

  std::cout<<"a = "<<a<<" b = "<<b<<std::endl;
  std::cout<<"first = "<<first<<" last = "<<last<<std::endl;    

  int c = 50 , d = 100;
  std::string name = "abc" , surname = "def";

  swap1(c,d);
  swap1(name,surname);

  std::cout<<"c = "<<c<<" d = "<<d<<std::endl;
  std::cout<<"name = "<<name<<" surname = "<<surname<<std::endl;    

  swap(c,d);
  swap(name,surname);

  std::cout<<"c = "<<c<<" d = "<<d<<std::endl;
  std::cout<<"name = "<<name<<" surname = "<<surname<<std::endl;    

  return 0;
}

**Output**
a = 10 b = 20
first = Bye last = hi
c = 50 d = 100
name = abc surname = def
c = 50 d = 100
name = def surname = abc

Les deux swap()etswap1() fondamentalement ont les mêmes définitions de fonctions, alors pourquoi n'échange swap()que les chaînes, alors swap1()que non?

Pouvez-vous également me dire comment les chaînes stl sont passées comme arguments par défaut, c'est-à-dire si elles sont passées par valeur ou par référence?

gettingBetterprogrammer
la source
4
Quel est le problème avec std :: swap ?
Jesper Juhl
Rien de mal à cela. J'apprenais des fonctions modélisées. J'ai donc écrit ce code juste pour m'entraîner mais la sortie m'a embrouillé.
gettingBetterprogrammer

Réponses:

9

Je peux voir pourquoi les gens froncent les sourcils sur ADL maintenant ...

Ce que vous voyez est un effet de la recherche dépendante de l' argument . Si vous ajoutiez une impression à l'intérieur de votre swapimplémentation, vous remarqueriez qu'elle n'est pas appelée std::string, seulement pour int.

std::swapest préférable à votre version, car il existe une spécialisation explicite pour le std::basic_stringtype. S'il n'existait pas, l'appel serait probablement ambigu.
Pour int, l'espace de noms stdn'est pas pris en compte dans le processus de recherche, votre version est donc la seule acceptable.

Pouvez-vous également me dire comment les chaînes stl sont passées comme arguments par défaut, c'est-à-dire sont-elles passées par valeur ou par référence?

Tout en C ++ est passé par valeur, sauf si vous le marquez explicitement comme passe-par-référence.

Yksisarvinen
la source
consultez ce code ici: pastebin.com/E257yw04 . Ma fonction swap1 () est appelée pour les chaînes, mais une seule fois. Pourquoi donc?
gettingBetterprogrammer
@dumb_programmer Vous avez deux appels à swap1 dans votre code (un pour intet un pour std::string), et donc deux appels sont imprimés. Il y a deux appels à swapwith std::string, et ceux-ci utilisent std::swap(pas d'impression).
Yksisarvinen
Je l'ai!! Merci beaucoup.
gettingBetterprogrammer
@dumb_programmer Remarque: veuillez ne pas vous appeler stupide. Le syndrome de l'imposteur est courant dans ce travail, mais la valeur réelle du programmeur n'est pas «combien il sait» mais plutôt «combien est-il disposé à apprendre». Vous n'avez pas compris quelque chose, alors vous avez tendu la main et demandé - c'est la meilleure action possible à faire (après avoir googlé d'abord bien sûr).
Yksisarvinen
Oui, je m'améliore de jour en jour! Merci pour votre réponse @Yksisarvinen Je vais bientôt changer mon nom d'utilisateur.
gettingBetterprogrammer
0

Vous passez des paramètres par valeur. Vous devez les transmettre par référence:

template <typename T> void myswap(T& a , T& b);

Ou - plus généralement - par référence globale (rvalue):

template <typename T> void myswap(T&& a , T&& b);
Red.Wave
la source