2010-02-17 31 views
5

Đây là một đoạn của một lớp mẫu mà đang gây ra lỗi biên dịch:dự kiến ​​lồng nhau-tên-specifier trước 'sktraits'

/* Secondary index class */ 
template<class TKey, class TVal, class key_traits, class val_traits> 
template<class TSecKey, class sktraits> 
class CBtreeDb<TKey, TVal, key_traits, val_traits>::CDbSecondaryIndex: protected CBtreeDb<TKey, TVal>, public IDeallocateKey 
{ 
public: 
typedef TSecKey   skey_type; 
typedef typename sktraits       skey_traits; 
typedef CNewDbt<TSecKey, sktraits>    CDbSKey; 
typedef typename iterator_t<TSecKey, skey_traits> iterator; 
typedef typename iter_lower_bound_t<skey_type> iter_lower_bound; 
typedef typename iter_upper_bound_t<skey_type> iter_upper_bound; 

CDbSecondaryIndex(CDbEnv* pEnv, u_int32_t flags, bool bAllowDuplicates=false): 
    CBtreeDb(pEnv, flags, bAllowDuplicates) 
{ 

} 

    // Class implementation continues ... 
}; 

Thông điệp biên dịch lỗi tôi nhận được là:

expected nested-name-specifier before 'sktraits'. 

Trên thực tế , lỗi này xảy ra trên mọi tuyên bố typedef sau đó typename

Tôi đã biên dịch mã này thành công trong quá khứ bằng cách sử dụng VS2005 và VS2008 trên X P.

Tôi hiện đang xây dựng trên Ubuntu 9.10, sử dụng gcc 4.4.1

Tôi nhìn lỗi này trên Google và nó xuất hiện rằng typename là không cần thiết trên dòng (nơi lỗi xảy ra), vì giả định tiêu chuẩn là một định danh trong vị trí đó là một kiểu. g ++ dường như đang phàn nàn vì nó mong đợi bất kỳ tuyên bố typename nào có đủ điều kiện (tức là A :: B).

Đây có phải là chẩn đoán chính xác về sự cố không - nếu có, thì làm cách nào để "hoàn toàn đủ điều kiện" typename?

Tóm lại, làm thế nào tôi có thể giải quyết vấn đề này?

+0

Tôi đã cố sửa lỗi này (ví dụ: lấy mã để biên dịch) - chỉ cần xóa 'typename' theo sau từ chối typdef. Mặc dù tiêu đề biên dịch thành công ngay bây giờ, tôi vẫn không hài lòng vì tôi muốn biết nguyên nhân cơ bản (lý do kỹ thuật) tại sao tôi phải xóa tên tệp (đặc biệt khi ký hiệu tương tự được sử dụng trong các lớp STL) –

Trả lời

0

Sau đây là không được phép:

template<class A> 
template<class B> class F { ... }; 

Bạn có thể có nhiều nhất một template<> đặc điểm kỹ thuật trước khi một định nghĩa lớp/chức năng.

+0

Vui lòng giải thích. Comeau mọi người không đồng ý: http: //www.comeaucomputing.com/techtalk/templates/# outsidedef - Tôi không có tiêu chuẩn tiện dụng nhưng Comeau là tiêu chuẩn tuân thủ tiêu chuẩn khá đáng tin cậy. –

+0

Tiêu chuẩn nói trong 14.5.2/1: "Mẫu thành viên của một mẫu lớp được định nghĩa bên ngoài định nghĩa mẫu lớp của nó phải được xác định với các tham số mẫu của mẫu lớp, theo sau là các tham số-mẫu của mẫu thành viên ", và đưa ra một ví dụ:' mẫu mẫu int chuỗi :: so sánh (const T2 & s) '. –

7

typename là cần thiết để chỉ định rằng một tên là phụ thuộc thực tế là một loại. Tên của bạn không phải là tên phụ thuộc, vì vậy không yêu cầu hoặc cho phép typename.

Cập nhật Các tiêu chuẩn thực sự có định nghĩa cú pháp sau:

typename-Speci fi er:
    typename lồng nhau-tên-Speci fi er identi fi er
    typename nested- name-speci fi er mẫu opt đơn giản-template-id

Hai nơi khác mà bạn có thể sử dụng từ khóa typename là trong danh sách tham số mẫu và trong tờ khai using (trong trường hợp thứ hai nó cũng phải được theo sau bởi một bộ định danh tên lồng nhau).

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