2013-05-15 23 views
7

Khi tôi có hai quá tải chức năng templated như thế này:hàm mẫu quá tải: const * vs const &

template<class T> 
void foo(T const&) 
{ 
    // do something with a const reference 
    cout << "const reference version"; 
} 

template<class T> 
void foo(T const*) 
{ 
    // do something with a const pointer 
    cout << "const pointer version"; 
} 

Tại sao biên dịch chọn phiên bản đầu tiên khi khởi tạo với một kiểu con trỏ không const?

int* bar; 
foo(bar); // prints "const reference version" 

char const* baz; 
foo(baz); // prints "const pointer version" 
+2

Bạn có thể tìm thấy giải thích tốt về vấn đề này trên kênh 9: http://channel9.msdn.com/Series/C9-Lectures-Stephan-T-Lavavej-Core-C-/Stephan-T-Lavavej-Core -Cpp-3-of-n. Nhưng về cơ bản Mark B trả lời câu hỏi của bạn. – mkaes

Trả lời

4

Lý do là vì bar là một con trỏ không const, vì vậy int* const& thực sự là một trận đấu tốt hơn so với int const* bởi vì nó không phải thêm const để kiểu con trỏ.

Nếu barconst đủ điều kiện thì đó sẽ là đối sánh chính xác cho phiên bản T const*.

0

template<class T> void foo(T const*) yêu cầu con trỏ const trên T. Vâng, nếu nó là tuyên bố duy nhất bạn đã có, sẽ có một lỗi biên dịch như bạn đang cố gắng để vượt qua một con trỏ không const như đối số.

Với template<class T> void foo(T const&) loại T phỏng đoán là int* được đưa ra bằng cách tham chiếu đến hàm.

2
#include <iostream> 
using namespace std; 
void foo(int const&) { 
    cout << "const reference" << endl; 
} 

void foo(int const*) { 
    cout << "const pointer" << endl; 
} 

int main() { 
    int *hi; 
    foo (hi); //const pointer 
    foo((*hi)); //const reference 
    foo(&(*hi));//const pointer 
} 

Thỏa thuận ở đây là tham chiếu và con trỏ khác nhau. Một con trỏ là một kiểu duy nhất, khi mà tham chiếu đến một giá trị không khác với giá trị của chính nó, hay đúng hơn là một bí danh cho đối tượng. Vì vậy, ví dụ, phiên bản này của mã trên sẽ không biên dịch.

#include <iostream> 
using namespace std; 
void foo(int const&) { 
    cout << "const reference" << endl; 
} 

void foo(int) { 
    cout << "hi there" << endl; 
} 

int main() { 
    int hi; 
    foo(hi); //const reference 
} 

Do các khai báo của foo không rõ ràng. Trình biên dịch không thể quyết định giữa chúng.

+0

cảm ơn vì sự trình diễn không rõ ràng – idefixs

1

Bạn có thể xác định điều gì đang xảy ra với các loại mẫu của mình bằng cách sử dụng typeid.

#include <iostream> 
#include <typeinfo> 
using namespace std; 

template<class T> void foo(T const&) { 
    cout << "const reference version T="<< typeid(T).name()<<endl; 
} 

template<class T> void foo(T const*) { 
    cout << "const pointer version T="<<typeid(T).name()<<endl; 
} 

int main() { 
    int* i_ptr=0; 
    foo(i_ptr); 

    const int* ci_ptr=0; 
    foo(ci_ptr);  
} 

đầu ra này (lưu ý đầu ra chính xác sẽ phụ thuộc vào trình biên dịch của bạn)

const reference version T=Pi 
const pointer version T=i 

nào cho thấy rằng trong trường hợp đầu tiên T = int* và kiểu lập luận đầy đủ là int* const&, và trong lần thứ hai T=int và đầy đủ loại đối số là int const *.