2010-09-17 28 views
6

Tôi đang cố viết hàm để thể hiện các thùng chứa STL chung (vectơ, danh sách, v.v.). Tôi đã cho hàm một tham số mẫu T, ví dụ, có thể đại diện cho vectơ. Tôi đang gặp vấn đề nhận được một iterator kiểu T.Lỗi với T :: iterator, trong đó tham số mẫu T có thể là vector <int> hoặc danh sách <int>

vector<int> v(10, 0); 
repr< vector<int> >(v); 

...

template <typename T> 
void repr(const T & v) 
{ 
    cout << "["; 
    if (!v.empty()) 
    { 
     cout << ' '; 
     T::iterator i; 
     for (i = v.begin(); 
      i != v.end()-1; 
      ++i) 
     { 
      cout << *i << ", "; 
     } 
     cout << *(++i) << ' '; 
    } 
    cout << "]\n"; 
} 

...

[email protected]:~/Desktop/stl$ g++ -Wall main.cpp 
main.cpp: In function ‘void repr(const T&)’: 
main.cpp:13: error: expected ‘;’ before ‘i’ 
main.cpp:14: error: ‘i’ was not declared in this scope 
main.cpp: In function ‘void repr(const T&) [with T = std::vector<int, std::allocator<int> >]’: 
main.cpp:33: instantiated from here 
main.cpp:13: error: dependent-name ‘T::iterator’ is parsed as a non-type, but instantiation yields a type 
main.cpp:13: note: say ‘typename T::iterator’ if a type is meant 

tôi đã cố gắng 'typename T :: iterator' là trình biên dịch đề xuất, nhưng chỉ có một lỗi khó hiểu hơn.

Chỉnh sửa: Cảm ơn các bạn đã trợ giúp! Dưới đây là một phiên bản làm việc cho bất cứ ai muốn sử dụng chức năng này:

template <typename T> 
void repr(const T & v) 
{ 
    cout << "["; 
    if (!v.empty()) 
    { 
     cout << ' '; 
     typename T::const_iterator i; 
     for (i = v.begin(); 
      i != v.end(); 
      ++i) 
     { 
      if (i != v.begin()) 
      { 
       cout << ", "; 
      } 
      cout << *i; 
     } 
     cout << ' '; 
    } 
    cout << "]\n"; 
} 
+0

Làm cách nào để đăng thông báo lỗi "khó hiểu hơn"? –

+4

btw, bạn có thể muốn thay thế v.end() - 1 bằng một cái gì đó khác mà các bộ lặp không hỗ trợ RandomAccess cũng hỗ trợ. – sellibitze

Trả lời

18

Bạn cần typename nói với trình biên dịch rằng ::iterator được coi là một loại. Trình biên dịch không biết rằng đó là một kiểu vì nó không biết T là gì cho đến khi bạn khởi tạo mẫu. Nó cũng có thể tham khảo một số thành viên dữ liệu tĩnh, ví dụ. Đó là lỗi đầu tiên của bạn.

Lỗi thứ hai của bạn là v là tham chiếu đến const. Vì vậy, thay vì ::iterator bạn phải sử dụng ::const_iterator. Bạn không thể yêu cầu một container liên tục cho một iterator không-const.

+0

Ai đã bỏ phiếu cho câu trả lời này? Câu trả lời là chính xác. –

+0

Không quá nhiều đến mức trình biên dịch không biết cái gì là ':: iterator', nhưng tiêu chuẩn đòi hỏi nó phải diễn giải nó như là một kiểu không, vì nó được đặt vào thông báo lỗi:" depend-name "' T :: iterator' 'được phân tích cú pháp dưới dạng không phải kiểu, nhưng instantiation tạo ra một loại " – visitor

+2

Tôi thấy. Vì vậy, tóc chia tách này sẽ biện minh cho một downvote. – sellibitze

3

Thay đổi T::iterator i; để typename T::const_iterator i;::iterator là loại Tv là một const &.

Trước một loại phụ thuộc đủ điều kiện, bạn cần typename. Nếu không có typename, có quy tắc phân tích cú pháp C++ cho biết rằng tên phụ thuộc đủ điều kiện phải được phân tích cú pháp là non-types ngay cả khi dẫn đến lỗi cú pháp.

typename tuyên bố rằng tên sau cần được coi là loại. Nếu không, tên được diễn giải để chỉ các loại không phải.

Các vấn đề liên quan