2010-04-25 5 views
5

아래 코드와 관련하여 컴파일러에서 호출 할 템플릿 함수를 선택하는 방법은 무엇입니까? const T & 함수가 생략되면 T & 함수가 항상 호출됩니다. T & 함수가 생략되면 const T & 함수가 항상 호출됩니다. 둘 모두 포함 된 경우 결과는 다음과 같습니다.컴파일을 통해 어떤 템플릿 함수를 호출 할 수 있습니까?

#include <iostream> 
#include <typeinfo> 

template <typename T> 
void function(const T &t) 
{ 
    std::cout << "function<" << typeid(T).name() << ">(const T&) called with t = " << t << std::endl; 
} 

template <typename T> 
void function(T &t) 
{ 
    std::cout << "function<" << typeid(T).name() << ">(T&) called with t = " << t << std::endl; 
} 

int main() 
{ 
    int i1 = 57; 
    const int i2 = -6; 

    int *pi1 = &i1; 
    int *const pi3 = &i1; 
    const int *pi2 = &i2; 
    const int *const pi4 = &i2; 

    function(pi1); ///just a normal pointer -> T& 
    function(pi2); ///cannot change what we point to -> T& 
    function(pi3); ///cannot change where we point -> const T& 
    function(pi4); ///cannot change everything -> const T& 

    return 0; 
} 

/* g++ output: 
function<Pi>(T&) called with t = 0x22cd24 
function<PKi>(T&) called with t = 0x22cd20 
function<Pi>(const T&) called with t = 0x22cd24 
function<PKi>(const T&) called with t = 0x22cd20 
*/ 

/* bcc32 output: 
function<int *>(T&) called with t = 0012FF50 
function<const int *>(T&) called with t = 0012FF4C 
function<int *>(const T&) called with t = 0012FF50 
function<const int *>(const T&) called with t = 0012FF4C 
*/ 

/* cl output: 
function<int *>(T&) called with t = 0012FF34 
function<int const *>(T&) called with t = 0012FF28 
function<int *>(const T&) called with t = 0012FF34 
function<int const *>(const T&) called with t = 0012FF28 
*/ 
+0

약간의 트릭에

typedef int * Pint const Pint int2 

분명히 상수 포인터. '__PRETTY_FUNCTION__'은 템플릿 매개 변수 유형 [ "Pi"대신 "int *"]을 포함하여 함수를 설명하는 올바른 형식의 문자열을 제공합니다. g ++에서'typeid (T) .name()'에 대한 기본 동작이 꽤 비밀 스럽기 때문에 템플릿이 어떻게 작동 하는지를 배울 때 이것은 매우 귀중하다는 것을 알았습니다. 나는'__FUNCSIG__'이 VS에서 비슷한 기능을 제공한다고 믿지만 검증 할 수있는 권한이 없다. –

답변

3

Here은 컴파일러가 수행하는 프로세스에 대한 간략한 요약입니다. 모든 것을 다루는 것은 아니지만 시작하게 만듭니다.

이 경우 결정은 템플리트되지 않은 기능과 동일하게 만들어집니다. void f(int&)void f(const int&)이 주어지면 첫 번째는 일반 int에 대해 선택되고 두 번째는 const int에 대해 선택됩니다. 변수는 사용자가 수정할 수있는 변수를 제공하면 변수를 수정할 수있는 함수를 호출하고 수정할 수없는 변수를 제공하면 변수를 수정할 수없는 함수를 호출합니다.

예제 코드에서 const int *으로 선언 된 pi2은 상수 데이터에 대한 상수 포인터가 아닙니다. 따라서 귀하의 기능 내에서 t을 변경할 수는 있지만 *t은 변경할 수 없습니다. 반대로 pi3은 상수가 아닌 데이터에 대한 상수 포인터입니다. 따라서 *t을 변경할 수는 있지만 t은 변경할 수 없습니다. 당신이 약간 코드를 변경 한 경우

: *pi1*pi3 유형 int&의 모두 따라서 변경 될 수 있기 때문에이 경우

function(*pi1); 
function(*p12); 
function(*pi3); 
function(*pi4); 

을, 첫 번째와 세 번째는 둘 다 T& 버전으로 해결하는 것입니다. *pi2*pi4은 모두 const int&이므로 과부하로 해석됩니다.

0

변수 자체가 상수인지 여부는 다음과 같습니다. 첫 번째 변수는 항상 일정하지 않습니다. 두 번째 점은 상수이지만 점을 변경할 수있는 곳은 두 번째 점과 네 번째 점 모두 상수 포인터입니다. 변수 자체가 const 인 것을 의미하기 때문에 점을 지정하면 변경할 수 없습니다.

typedef const int Cint; 
Cint * int1; 

분명히 정수 int에 대한 포인터. 당신 ++ g을 사용하여 될 일이 일정하지 않은 INT

관련 문제