2012-09-04 3 views
4

오늘 저는 C++ 템플릿 함수 인수 추론 및 템플릿 함수 오버로드 해결 방법을 C++ 11 (vs2010 sp1을 사용하고 있습니다)에서 제기하고 싶습니다. 나는 다음과 같이 두 가지 템플릿 함수 정의 :C++ 템플릿 함수 인수 추론 및 함수 해결

기능 # 1 :

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

기능 # 2 :

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);} 
} 

I :

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

이제 다음 코드를 고려를 이 시나리오에서 함수 오버로딩의 지침 뒤에있는 규칙을 알고 싶을뿐입니다. 이오스.

아래의 두 답변에 동의하지 않습니다. const int 예제가 리터럴 문자열 예제와 다릅니다. 나는 CONST의 INT의 예에서 지구

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”); 

에서 유추 된 형식이 무엇을 볼 수 #function 1을 약간 수정할 수 있으며, "CONST T &"선언에서 const를 수정은 CONST의 INT의 "를 const와"를 먹고 ; 리터럴 문자열 예제에서는 "const T &"선언에서 const 수정자가 어디로 가는지 알지 못합니다. & const를 선언하는 것은 의미가 없습니다 (int * const를 선언하는 것은 의미가 있습니다).

+2

. 새 버전을 읽고 중요하다고 생각되는 항목을 다시 추가하십시오 (그리고 놓친 내용). – Mankarse

+1

@ 레오 니드 : 당신은 무엇을 피우고 있습니까? * const가 아닌 lvalue *가 rvalue reference가되도록 추론 하시겠습니까? 그것은 광기입니다. 'int '로 추론 된 T는 완벽하게 정확합니다. – Puppy

+0

@DeadMG - 정확합니다. 'int'로 추론됩니다. 나는 그것에 대해 생각하지 않고'func()'에 의해 인쇄 된 것을 잘라내어 붙여 넣었다. –

답변

5

트릭은 const입니다. F1과 F2는 어떤 유형의 값이라도 받아 들일 수 있지만, F2는 더 좋은 일치입니다. 왜냐하면 완벽한 전달이기 때문입니다. 값이 const lvalue가 아니면 F2가 가장 일치합니다. 그러나 lvalue가 const 인 경우 F1이 더 적합합니다. 이것이 const int와 문자열 리터럴에서 선호되는 이유입니다.

1

과부하 # 2는 T & 및 T & &에 대해 정확히 일치합니다. 따라서 두 가지 오버로드는 rvalue 및 lvalue에 바인딩 될 수 있습니다. 귀하의 예제에서 과부하 차별화는 대부분 일정에 따라 이루어집니다. 1 과부하에 const T&에 대한 일치 - "feng" 리터럴 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”)} 

const char(&)[5] 때문이다 정확히 일치 -

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

0int&&입니다. (&)은 이것이 참조임을 나타냅니다.

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

배열 - char(&)[5]입니다 - 2 과부하에 T&에 대한 일치

나는 그것이 훨씬 더 쉽게 읽을 수 있도록하기 위해 질문을 수정했지만, 나는 이해할 수 없었다 일부 섹션을 떨어
+0

'{func (0);}'이'const T &'버전을 사용하기를 기대했습니다.'T &&'가 왜 선택 되었습니까? 이 경우 T는'const int'이다. –

+0

아니요,'0'은'int &&'입니다 - 표준에서는 그렇게 말합니다. –

+0

나는 너와 동의하지 않는다. 나는 약간의 증거를 보충했다. – changFeng