2013-07-16 28 views
19

Tôi nhận được lỗi biên dịch khi cố gắng gọi hàm tạo lớp cơ sở trong danh sách khởi tạo bắt nguồn khi sử dụng thông số mẫu mẫu với CRTP.clang ++ không chấp nhận sử dụng tham số mẫu mẫu khi sử dụng CRTP

Vấn đề có thể được nhân rộng với đoạn mã này:

template <template<class> class Derived, class T> 
struct base 
{ 
}; 

template <class T> 
struct derived : public base<derived, T> 
{ 
    derived() 
     : base<derived, T>() 
    { } 
}; 

Các lỗi vi phạm Thông tin về:

bug.cpp:10:16: error: template argument for template template parameter must be a class template or type alias template 
     : base<derived, T>() 
      ^
bug.cpp:10:11: error: expected class member or base class name 
     : base<derived, T>() 
     ^
bug.cpp:10:11: error: expected '{' or ',' 
3 errors generated. 

Vấn đề này chỉ xuất hiện xảy ra trên kêu vang (3.4), không g ++ (4.8, 4.7, 4.6). Tôi đang biên dịch với -std = C++ 11 cũng.

Đây là lần đầu tiên tôi cần sử dụng CRTP với thông số mẫu mẫu. Tôi làm điều này được không và đó là một vấn đề với clang ++ hay không?

Tôi đã phát triển để tin tưởng các thông báo lỗi clang ++ nhiều hơn g ++ vào cuối!

Trả lời

17

Mã của bạn là hợp pháp.

Từ C++ 11 Standard, phần 14.6.1:

Giống như (không mẫu) các lớp học bình thường, lớp mẫu có tiêm-class-name (khoản 9). Tên lớp được tiêm có thể được sử dụng làm tên mẫu hoặc tên loại. Khi được sử dụng với mẫu-đối số-danh sách, làm mẫu-đối số cho mẫu mẫu tham số hoặc dưới dạng cuối cùng được xác định trong kiểu khai báo mẫu lớp bạn bè, với chính lớp mẫu.

Có vẻ như phiên bản clang của bạn vẫn đang triển khai quy tắc cũ. Dựa trên các nhận xét bổ sung của bạn, nó có thể chỉ làm như vậy trong danh sách ctor-initializer ctor-initializer.


tài David Rodríguez - dribeas cung cấp một cách giải quyết cho các trình biên dịch chưa thực hiện đầy đủ C++ 11 quy tắc tiêm-class-name. Sử dụng bất kỳ tên của lớp đó không phải là không đủ tiêu chuẩn, ví dụ:

derived() 
    : base< ::derived, T >() 
//   ^^ qualified with global namespace 
{ } 

Một số trình biên dịch có thể yêu cầu này trong danh sách thừa kế cũng:

template <class T> 
struct derived : public base< ::derived, T > 
//       ^^ 
+0

+1 Không biết rằng điều này đã thay đổi trong C++ 11. Bạn có thể muốn cung cấp giải pháp thay thế mà tôi có trong câu trả lời đã xóa. –

+0

@ DavidRodríguez-dribeas: đừng lo, tiêu chuẩn mới vẫn làm tôi ngạc nhiên thường xuyên. –

+1

Tôi không lo lắng, ngược lại tôi đã học được điều gì đó. Tôi sẽ lo lắng về ngày tôi không học bất cứ điều gì mới :) –

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