Вывод аргумента функции шаблона c ++ и разрешение функции

Сегодня я просто хочу поднять вопрос о выводе аргументов функции шаблона C ++ и разрешении перегрузки функции шаблона в c ++ 11 (я использую vs2010 sp1).
Я определил две функции шаблона, как показано ниже:

функция № 1:

template <class T>
void func(const T& arg)
{
cout << "void func(const T&)" <<endl;
}

функция № 2:

template <class T>
void func(T&& arg)
{
cout << "void func(T&&)" <<endl;
}

Теперь рассмотрим следующий код:

int main() {
//I understand these first two examples:

//function #2 is selected, with T deduced as int&
//If I comment out function #2, function#1 is selected with
//T deduced as int
{int a = 0; func(a);}

//function #1 is selected, with T is deduced as int.
//If I comment out function #1, function #2 is selected,
//with T deduced as const int&.
{const int a = 0; func(a);}

//I don't understand the following examples:

//Function #2 is selected... why?
//Why not function #1 or ambiguous...
{func(0);}

//But here function #1 is selected.
//I know the literal string “feng” is lvalue expression and
//T is deduced as “const char[5]”. The const modifier is part
//of the T type not the const modifier in “const T&” declaration.
{func(“feng”)}

//Here function#2 is selected in which T is deduced as char(&)[5]
{char array[] = “feng”; func(array);}
}

Я просто хочу знать правила, лежащие в основе разрешения перегрузки функций в этих сценариях.

Я не согласен с этими двумя ответами ниже. Я думаю, что пример const int отличается от примера с литеральной строкой. Я могу немного изменить #function 1, чтобы увидеть, какой тип выводится на земле.

 template <class T>
void func(const T& arg)
{
T local;
local = 0;
cout << "void func(const T&)" <<endl;
}
//the compiler compiles the code happily
//and it justify that the T is deduced as int type
const int a = 0;
func(a);

template <class T>
void func(const T& arg)
{
T local;
Local[0] = ‘a’;
cout << "void func(const T&)" <<endl;
}
//The compiler complains that “error C2734: 'local' : const object must be
//initialized if not extern
//see reference to function template instantiation
//'void func<const char[5]>(T (&))' being compiled
//    with
//    [
//        T=const char [5]
//    ]

Func(“feng”);

в примере const int модификатор const в «const T&Декларация пожирает «константу» const int; хотя в примере с литеральной строкой я не знаю, где находится модификатор const в «const T»&Декларация идет. Бессмысленно объявлять что-то вроде int& const (но имеет смысл объявить int * const)

4

Решение

Хитрость здесь в том, const, И F1, и F2 могут принимать любое значение любого типа, но в целом F2 лучше подходит, потому что это идеальная пересылка. Так что, если значение не является const lvalue, F2 — лучший матч. Тем не менее, когда lvalue const, F1 лучший матч. Вот почему он предпочтителен для const int и строкового литерала.

5

Другие решения

Обратите внимание, что перегрузка # 2 является точным соответствием для T& и т&&, Таким образом, обе перегрузки могут связываться с rvalue и lvalue. В ваших примерах разграничение перегрузки выполняется в основном по постоянству.

//Function #2 is selected... why?
//Why not function #1 or ambiguous...
{func(0);}

0 является int&& — точное совпадение для T&&

//But here function #1 is selected.
//I know the literal string “feng” is lvalue expression and
//T is deduced as “const char[5]”. The const modifier is part
//of the T type not the const modifier in “const T&” declaration.
{func(“feng”)}

буквальный "feng" является const char(&)[5] — точное совпадение для const T& в 1-й перегрузке. (&) указывает, что это ссылка.

//Here function#2 is selected in which T is deduced as char(&)[5]
{char array[] = “feng”; func(array);}

массив — есть char(&)[5] — точное совпадение для T& во 2-й перегрузке

1

По вопросам рекламы [email protected]