Próba użycia szablonowych funkcji do zamiany dwóch łańcuchów

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

Zarówno swap()i swap1()zasadniczo mają te same definicje funkcji, to dlaczego swap()właściwie tylko zamienia ciągi, a swap1()nie ma?

Czy możesz mi również powiedzieć, że w jaki sposób łańcuchy stl są domyślnie przekazywane jako argumenty, tj. Czy są przekazywane przez wartość czy przez odwołanie?

gettingBetterprogrammer
źródło
4
Co jest nie tak z std :: swap ?
Jesper Juhl
1
Nie ma w tym nic złego. Uczyłem się o funkcjach opartych na szablonach. Więc napisałem ten kod tylko po to, aby ćwiczyć, ale wynik mnie pomylił.
gettingBetterprogrammer

Odpowiedzi:

9

Rozumiem, dlaczego ludzie marszczą teraz ADL ...

To, co widzisz, jest efektem wyszukiwania zależnego od argumentu . Jeśli dodasz wydruk w swojej swapimplementacji, zauważysz, że nie jest on wymagany std::string, tylko dla int.

std::swapjest preferowane w stosunku do twojej wersji, ponieważ istnieje wyraźna specjalizacja dla std::basic_stringtypu. Gdyby nie istniał, połączenie byłoby prawdopodobnie dwuznaczne.
Ponieważ intprzestrzeń nazw stdnie jest uwzględniana w procesie wyszukiwania, więc Twoja wersja jest jedyną akceptowalną.

Czy możesz mi również powiedzieć, że w jaki sposób łańcuchy STL są domyślnie przekazywane jako argumenty, tj. Czy są przekazywane przez wartość czy przez odwołanie?

Wszystko w C ++ jest przekazywane przez wartość, chyba że wyraźnie oznaczysz je jako referencję.

Yksisarvinen
źródło
sprawdź ten kod tutaj: pastebin.com/E257yw04 . Moja funkcja swap1 () jest wywoływana dla ciągów, ale tylko raz. Dlaczego?
GettingBetterprogrammer
@dumb_programmer W kodzie masz dwa wywołania swap1 (jedno dla inti jedno dla std::string), więc dwa połączenia są drukowane. Istnieją dwa połączenia swapz std::stringi te używają std::swap(bez drukowania).
Yksisarvinen
Rozumiem!! Dziękuję bardzo.
GettingBetterprogrammer
@dumb_programmer Uwaga dodatkowa: nie nazywaj siebie głupcem. Syndrom impostera jest powszechny w tej pracy, ale prawdziwą wartością programisty nie jest „ile on wie”, ale „ile jest gotów się nauczyć”. Coś nie zrozumiałeś, więc wyciągnąłeś rękę i spytałeś - to najlepsze możliwe działanie (oczywiście najpierw po googlowaniu).
Yksisarvinen
Tak, jestem coraz lepszy każdego dnia! Dzięki za odpowiedź @Yksisarvinen Wkrótce zmienię nazwę użytkownika.
gettingBetterprogrammer
0

Przekazujesz parametry według wartości. Musisz przekazać je przez odniesienie:

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

Lub - bardziej ogólnie - według globalnego (rvalue) odniesienia:

template <typename T> void myswap(T&& a , T&& b);
Red.Wave
źródło