2010-06-25 32 views
6

Tôi đang chuyển mã C++ của windows (msvc & intel) sang Linux (g ++). Mã này sử dụng rất nhiều mẫu (tôi thích metaprogramming ;-). Nhưng tôi không thể biên dịch mã này:g ++ mẫu vấn đề

template <class TA> 
struct A 
{ 
    template <class TAB> struct B; 
}; 


template <class TC> 
struct C {}; 


template <class TD> 
struct D 
{ 
    template <class TTD> class T {}; 
}; 


template<class TA> 
    template<class TBA> 
struct A<TA>::B : C<typename D<TA>::T<TBA> > 
{ 
    int foo; 
}; 

g ++ cho tôi biết rằng trong định nghĩa của A :: B, C có đối số mẫu không hợp lệ. Nhưng trên msvc và intel nó hoạt động tốt! Có vấn đề gì ở đây? PS: Rất tiếc, tôi không thể đăng mã gốc vì nó quá phức tạp. Nhưng ví dụ này hầu như giống nhau và cho cùng một lỗi trên g ++. Cảm ơn bạn.

CẬP NHẬT: Tôi đã tìm thấy sự cố trong đối số TBA của T. g ++ không giống như cách sử dụng mẫu thứ hai trong định nghĩa.

+0

I have seen that "mẫu mẫu struct ..." cú pháp trước đây nhưng tôi chưa bao giờ biết nó có ý nghĩa gì hay tại sao nó là cú pháp pháp. Có nghĩa là gì (khi "mẫu" được đề cập hai lần trước một cấu trúc như thế)? – Dennis

+1

@Dennis: Cần thiết cho định nghĩa mẫu lồng nhau bên ngoài mẫu kèm theo, xem ví dụ: [tại đây] (http://www.comeaucomputing.com/techtalk/templates/#outsidedef). –

+0

TA là đối số mẫu của A và TAB là đối số mẫu của A :: B – f0b0s

Trả lời

10

Bạn cần từ khóa template

template<class TA> 
    template<class TBA> 
struct A<TA>::B : C<typename D<TA>::template T<TBA> > 
{ 
    int foo; 
}; 

GCC là đúng để đưa ra một chẩn đoán ở đây. Điều này là do không thể tìm kiếm T trong phạm vi phụ thuộc D<TA>. Ý nghĩa của < sau khi nó phụ thuộc vào việc T là mẫu hay không. Tiêu chuẩn nói rằng T sẽ được giả định là không phải là mẫu và do đó, không thể theo sau một danh sách đối số mẫu theo thứ tự T.

template giống như typename ở chỗ nó yêu cầu trình biên dịch xử lý T làm mẫu và rằng < là khởi đầu của danh sách đối số trong mọi trường hợp. Standard nói trong đoạn 14.2/214.2/4

Đối với một mẫu tên tuổi để đủ điều kiện một cách rõ ràng bởi các đối số mẫu, tên phải được biết để chỉ một mẫu.

Khi tên của chuyên gia mẫu thành viên xuất hiện sau đó. hoặc -> trong biểu thức postfix, hoặc sau khi nested-name-specifier trong một id đủ điều kiện và biểu thức postfix hoặc id đủ điều kiện một cách rõ ràng phụ thuộc vào tham số mẫu (14.6.2), tên mẫu thành viên phải là bắt đầu bằng mẫu từ khóa. Nếu không, tên được giả định là đặt tên cho một mẫu không phải là mẫu.

Trong trường hợp của bạn, bạn có T xuất hiện sau khi lồng nhau-tên-specifier D<TA> mà phụ thuộc vào các mẫu tham số TA. Đối với công cụ chỉ định tên tệp để phân tích cú pháp chính xác, cấu trúc D<TA>::T<TBA> phải giải thích T làm tên của mẫu lớp, trong đó 14.2 cấm.


Mở chủ đề đó, nó luôn luôn là một ý tưởng tốt để thử và biên dịch với Clang

main1.cpp:21:37: error: use 'template' keyword to treat 'T' as a dependent template name 
struct A<TA>::B : C<typename D<TA>::T<TBA> > 
            ^
            template 
1 error generated. 
+1

BRILLIANT, THANX! – f0b0s

+0

ok, tôi hiểu rồi.tôi thout về từ khóa 'typename' thứ hai, nhưng bây giờ là một 'mẫu'. – f0b0s

+0

Wow, tôi thực sự thích thông báo chẩn đoán này, bây giờ đó là những gì bạn mong đợi từ trình biên dịch lý tưởng. –