Рассмотрим следующие функции
int f (const int& i)
{
cout << "in const reference function";
}
int f ( int &i)
{
cout << "in non const reference function";
}
int main()
{
int i;
f(3);
f(i);
}
В этом случае, когда вызов функции связан с определением функции, будет ли он во время компиляции или во время выполнения, поскольку один из них является lvalue i
а другой нет?
Кроме этого две функции одинаковы по количеству и типу параметров.
Перегрузка будет выбрана во время компиляции. Будет выбрано «наилучшее соответствие», которое в этом случае зависит от cv-квалификации параметров функции:
От N4140 [over.ics.rank] / 3
Две неявные последовательности преобразования одной и той же формы являются неразличимыми последовательностями преобразования, если только одна из
применяются следующие правила:
Стандартная последовательность преобразования S1 является лучшей последовательностью преобразования, чем S2, если
…
S1 и S2 являются привязками ссылок, и типы, на которые ссылаются ссылки, являются одинаковыми
type за исключением cv-квалификаторов верхнего уровня и типа, к которому относится ссылка, инициализированная S2
является более квалифицированным по cv, чем тип, к которому относится ссылка, инициализированная S1.
int&
менее квалифицированным, чем const int&
так будет выбираться по возможности. int&
не может связываться с таким значением 3
, Итак const
версия выбрана для этого.
Определяется во время компиляции
Этот код:
void f (const int& i)
{
return;
}
void f ( int &i)
{
return;
}
int main()
{
int i = 12;
f(3);
f(i);
}
компилируется с gcc 5.2 к этому:
movl $3, -4(%rbp) //Declare variable i with 3
leaq -4(%rbp), %rax
movq %rax, %rdi
call f(int const&) //And call the method with const int&
leaq -8(%rbp), %rax
movq %rax, %rdi
call f(int&) //Call the method with only the reference
Это будет сделано только во время компиляции, потому что тип параметров отличается.
Поэтому это не простые перегруженные функции, вызовы которых могут быть определены только во время компиляции.