2010-12-13 38 views
5

Tôi không biết tại sao các mã này không thể được biên dịch. Tôi đã được thử nghiệm trong Visual C++ 2010 và gcc với -std = C++ 0x. bất cứ ai đưa ra một số gợi ý? cảm ơn!Câu hỏi về sự sụp đổ tham chiếu C++ 0x

template<typename T> 
class Foo 
{ 
public: 
void test(const T&){cout<<"const";} 
void test(  T&){cout<<"non const";} 
}; 

int main() 
{ 
int a; 
Foo<int&> f; 
} 

biên dịch báo lỗi: 'void Foo :: test (T): hàm thành viên đã được xác định hoặc tuyên bố

nhưng tại sao điều này có thể được biên dịch?

template<typename T> void foo(const T&){cout<<"const"; } 
template<typename T> void foo(T&){cout<<"non const"; } 
int main() 
{ 
    int a; 
    foo<int&>(a); 
} 

I'v đọc C++ 0x bài viết cho biết: T & & == T &, vì vậy const T & & == const T &?

Trả lời

8

này:

Foo<int&> f; 

làm phát sinh instantiation này:

class Foo<int&> 
{ 
public: 
void test(int&); 
void test(int&); 
}; 

const áp dụng cho một loại đó là một tài liệu tham khảo là một không-op. Hãy so sánh nó với một hàm thành viên không tĩnh hoạt động trên một thành viên dữ liệu tham khảo:

struct A { 
    int &ref; 

    // valid: const member function doesn't treat "ref" as "const int&". 
    void operate() const { 
    ref = 0; 
    } 
}; 

Bạn phải vượt qua int để Foo<...> để đạt được mục tiêu của bạn.

13

i'v read c++0x article said: T& & ==T& , so const T& & == const T& ?

Thực ra, điều đó không có ý nghĩa gì nhiều. IMHO, nó tốt hơn để đưa điều này vào một bảng:

T  T&  const T  const T& 
--------------------------------------- 
int  int& const int const int& 
int& int& int&   int& 
     (1)  (2)   (1+2) 

1: Reference collapsing in action 
2: const applies to the reference and is therefore ignored 

Nếu T đã là một tài liệu tham khảo (2 hàng) const trong const T áp dụng cho các tài liệu tham khảo và không để trọng tài. Nhưng một tham chiếu vốn dĩ không đổi theo nghĩa là bạn không thể làm cho nó tham chiếu đến một đối tượng khác sau khi khởi tạo, do đó, const chỉ bị bỏ qua ở đây. Bạn có thể nghĩ về nó như "const sụp đổ". ;-)

1

Đối với câu hỏi thứ hai, hai hàm khởi tạo có cùng kiểu tham số và cả hai mẫu (nếu một mẫu, mẫu kia là hàm không phải mẫu, độ phân giải quá tải sẽ chọn sau), vì vậy độ phân giải quá tải sẽ chọn mẫu chuyên biệt hơn. Thông thường const T & là loại chuyên biệt hơn T &, vì vậy chức năng mẫu đầu tiên được gọi.