Intentando usar funciones templadas para intercambiar dos cadenas

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

Ambos swap()y swap1()básicamente tienen las mismas definiciones de funciones, ¿por qué solo swap()intercambia las cadenas, mientras swap1()que no?

Además, ¿puede decirme cómo se pasan las cadenas stl como argumentos de forma predeterminada, es decir, si se pasan por valor o por referencia?

GettingBetterprogrammer
fuente
44
¿Qué hay de malo con std :: swap ?
Jesper Juhl
No tiene nada de malo. Estaba aprendiendo sobre funciones templatizadas. Así que escribí este código solo para practicar, pero la salida me confundió, así que pregunté.
gettingBetterprogrammer

Respuestas:

9

Puedo ver por qué las personas desaprueban a ADL ahora ...

Lo que ves es un efecto de la búsqueda dependiente de argumentos . Si desea añadir una impresión dentro de su swapaplicación, se daría cuenta de que está no pidió std::string, sólo para int.

std::swapes preferible a su versión, porque existe una especialización explícita para el std::basic_stringtipo. Si no existiera, la llamada probablemente sería ambigua.
Para int, el espacio de nombres stdno se considera en el proceso de búsqueda, por lo que su versión es la única aceptable.

Además, ¿puede decirme cómo se pasan las cadenas stl como argumentos por defecto, es decir, si se pasan por valor o por referencia?

Todo en C ++ se pasa por valor, a menos que lo marque como paso por referencia explícitamente.

Yksisarvinen
fuente
mira este código aquí: pastebin.com/E257yw04 . Mi función swap1 () se llama para cadenas, pero solo una vez. ¿Porqué es eso?
gettingBetterprogrammer
@dumb_programmer Tiene dos llamadas para intercambiar1 en su código (una para inty otra para std::string), por lo que se imprimen dos llamadas. Hay dos llamadas a swapwith std::string, y aquellas que se usan std::swap(sin impresión).
Yksisarvinen
¡¡Entendido!! Muchas gracias.
gettingBetterprogrammer
@dumb_programmer Nota al margen: por favor, no te consideres tonto. El síndrome de impostor es común en este trabajo, pero el valor real del programador no es "cuánto sabe" sino más bien "cuánto está dispuesto a aprender". No entendiste algo, así que te acercaste y preguntaste: esta es la mejor acción posible (después de buscar en Google primero, por supuesto).
Yksisarvinen
Sí, estoy mejorando todos los días! Gracias por su respuesta @Yksisarvinen Cambiaré mi nombre de usuario pronto.
gettingBetterprogrammer
0

Estás pasando parámetros por valor. Debe pasarlos por referencia:

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

O, más generalmente, por referencia global (valor):

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