Перегрузка функций в C ++ перемещая аргументы из-за стоимости или из-за ссылки (Функтион Оверлоадинг)

Предполагая, что у нас есть этот пример функций в C ++

void foo(int x)  { std::cout << "foo(int)"   << std::endl; }
void foo(int& x) { std::cout << "foo(int &)" << std::endl; }

Существует возможность отличаться в какую функцию я хочу призвать реализовывая какое-то изменение в аргументах вызова?

Если призывается функция foo в любом из этих способов:

foo( 10);

i = 10;
foo( static_cast(i));

foo( static_cast(i)); // Aunque aquí convertir un tipo básico a través de una referencia no tiene mucha utilidad. Sólo es para exponer los casos posibles.

Призови первую двух перегруженных функций, потому что не возможно перемещать из-за ссылки постоянный аргумент в не постоянный параметр. Но: как он был бы сделан, чтобы мочь призывать вторую перегруженных функций? Если я реализую следующий призыв:

int i = 10;
foo( i);

Происходит ошибка двусмысленности, так как обе функции действительные для этого аргумента.

В этой ссылке https://stackoverflow.com / в / 5465379/6717386 он выставляет, что способ это решать, - в случае манипулирования объектами вместо основных типов, способствования тому, чтобы строительный copy был лишен, так что, не смогли реализовывать копию стоимости, он обязательно должен призывать вторую функцию и перемещать объект из-за ссылки. Но: и с основными типами какой-то способ существует? Обязательно нужно менять имя в функции, чтобы предотвращать этот тип проблем?

2
задан 23.05.2017, 15:39
1 ответ
int i = 10;
foo( i);

Происходит ошибка двусмысленности, так как обе функции действительные для этого аргумента.

Такой он, C ++ он не подготавливает никаким механизмом тому, чтобы отличать между вызовом из-за копии и вызова из-за ссылки, так что ответы в: и с основными типами какой-то способ существует? он был бы простым не.


Но это очень скучный ответ, так что мы попробуем использовать программные средства языка, чтобы пробовать выполнять цель:

void foo(int x)  { std::cout << "foo(int)"   << std::endl; }
void foo(int& x) { std::cout << "foo(int &)" << std::endl; }

Мы можем изменять поведение и нарушать двусмысленность используя оператор unario +:

int i = 10;
foo(+i); // Llamada no ambigua: llama foo(int)

Применяться оператор unario + на типе возврати Вашу стоимость, так что единственный доступный выбор - вызов в foo из-за копии (прощание двусмысленность!)... к несчастью это не решает нам призыв к версии из-за не постоянной ссылки.

Единственный способ это получать состоит в том, чтобы способствовать тому, чтобы один из двух выборов был лучше, что другая в случае двусмысленности, например способствуя тому, чтобы одна из функций была шаблоном:

template <typename T>
void foo(T x)  { std::cout   << "foo(int)"   << std::endl; }
void foo(int& x) { std::cout << "foo(int &)" << std::endl; }

int i = 10;
foo(i);  // Llamada no ambigua: foo(int&) es la mejor opcion
foo(10); // Llamada no ambigua: foo(T) es la mejor opcion

Когда составитель выбирает между версией шаблон и не шаблон, не шаблон - лучший выбор, итак заканчивается двусмысленность; к несчастью вышеупомянутый выбор подразумевает, что "Обязательно нужно менять имя в функции, чтобы предотвращать этот тип проблем", понимая "имя функций" под типом тех же самых.

2
ответ дан 24.11.2019, 13:39
  • 1
    Очень хороший opci и # 243; n это оператора unario, много м и # 225; s простой, что делать пробы в const. И большое спасибо из-за informaci и # 243; n decisi и # 243; n составителя между шаблоном и не шаблоном (stackoverflow в и # 250; n он не позволяет мне расставлять знаки препинания в сообщениях, схвати и # 237; за который я тебе благодарен из-за aqu и # 237;). – Carlos A. Gómez 16.08.2016, 21:15