Попытка использовать шаблонные функции, чтобы поменять две строки - PullRequest
9 голосов
/ 20 апреля 2020
#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

И swap(), и swap1() в основном имеют одинаковые определения функций, тогда почему только swap() фактически меняет строки, а swap1() - нет?

Также можете ли вы сказать мне, как строки stl передаются в качестве аргументов по умолчанию, т.е. передаются ли они по значению или по ссылке?

Ответы [ 2 ]

9 голосов
/ 20 апреля 2020

Теперь я понимаю, почему люди не одобряют ADL ...

То, что вы видите, это эффект Argument Dependent Lookup . Если вы добавите отпечаток в вашу swap реализацию, вы заметите, что , а не , требует std::string, только для int.

std::swap предпочтительнее вашей версии, поскольку существует явная специализация для типа std::basic_string. Если он не существует, вызов будет, вероятно, неоднозначным.
Для int пространство имен std не рассматривается в процессе поиска, поэтому ваша версия является единственно приемлемой.

Также вы можете сказать мне, как строки stl передаются как аргументы по умолчанию, т.е. передаются ли они по значению или по ссылке?

Все в C ++ передается по значению, если вы не пометите его как обход -отсылка явно.

0 голосов
/ 23 апреля 2020

Вы передаете параметры по значению. Вам нужно передать их по ссылке:

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

Или - в более общем смысле - по глобальной (rvalue) ссылке:

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