2009-09-24 26 views
24

Đã đọc xác nhận quyền sở hữu nhiều lần trong các bài viết - Tôi muốn thêm câu hỏi này vào Stackoverflow và yêu cầu cộng đồng - là mã sau có thể di chuyển không?Thùng chứa thư viện chuẩn có tham số mẫu tùy chọn bổ sung?

template<template<typename T, typename Alloc> class C> 
void f() { 
    /* some code goes here ... */ 
} 

int main() { 
    f<std::vector>(); 
} 

Việc triển khai cung cấp các thông số mẫu bổ sung, mặc định ngoài hai thông số nổi tiếng chưa? Điều này sẽ làm cho mã trên không được hình thành, vì nó giả định hai tham số mẫu. Xem đoạn cuối cùng in this article để biết ví dụ về khiếu nại đó.

Trả lời

22

Tôi tìm thấy issue report sau đây, mà nói

Không có sự mơ hồ; tiêu chuẩn rõ ràng như được viết. Người triển khai thư viện không được phép thêm tham số mẫu vào các lớp thư viện chuẩn. Điều này không thuộc quy tắc "như thể", do đó, nó sẽ chỉ được phép nếu tiêu chuẩn đã cấp giấy phép rõ ràng cho người triển khai thực hiện việc này. Điều này sẽ đòi hỏi một sự thay đổi trong tiêu chuẩn.

LWG quyết định không thực hiện thay đổi này, vì nó sẽ phá vỡ mã người dùng liên quan đến tham số mẫu mẫu hoặc chuyên môn của mẫu lớp thư viện chuẩn.

Sách và người nói việc triển khai có thể thêm các thông số tùy chọn khác có vẻ sai.

1

Kiểm tra các mục con của 17.4.4 [lib.conforming].

17.4.4.3/3 nói rằng "không thể khai báo chức năng toàn cầu hoặc không phải thành viên bằng cách thực hiện thêm đối số mặc định", nhưng 17.4.4.4/2 cho phép thay thế chữ ký chức năng thành viên được mô tả bằng chữ ký dài hơn vì các tham số bổ sung có mặc định.

Không có phần nào cho mẫu, vì vậy nếu chúng cảm thấy cần cung cấp 17.4.4.3/3, có vẻ như với tôi, các tham số mẫu bổ sung được phép chặn từ ngữ ngược lại.

+0

Ok, không bao giờ tâm trí - một báo cáo vấn đề rõ ràng là tốt hơn so với đoán của tôi: P – me22

0

Tôi cũng đã thấy xác nhận quyền sở hữu này. Nhưng.

Đối với một, tôi chưa bao giờ thấy triển khai thực hiện việc này. Tôi dường như nhớ rằng Andrei Alexandrescu đã từng dự tính sử dụng những thứ như loại cấp phát trên steroid (giống như my_fancy_thing<std::allocator,more_info_to_pass_to_the_container>, trong khi chỉ std::allocator vẫn hoạt động). Nhưng ngay cả điều này vẫn sẽ giữ cho f() của bạn hoạt động, và đó là điều gần nhất với việc thực hiện phá vỡ ví dụ của bạn mà tôi từng nghe được thảo luận.

Tôi nghĩ rằng điều này rơi khá nhiều vào cùng danh mục với tuyên bố rằng con trỏ 0 không nhất thiết phải được biểu thị bằng giá trị với tất cả các bit được đặt thành 0 - ngay cả khi nhà cung cấp thực sự có quyền tự do đó (mà tôi không có) Tôi biết, vì có những tuyên bố từ cả hai phía), họ sẽ không bao giờ sử dụng nó, bởi vì điều đó sẽ phá vỡ cơ bản tất cả các mã hiện có.

Vì vậy, tôi đã từ lâu đã quyết định không phải lo lắng về điều đó.

+0

Ai đó đã gửi một vấn đề và yêu cầu kéo cho [máy in đẹp] (http://louisdx.github.com/cxx-prettyprint/) một lần giả vờ rằng các đối số thừa đó đã thực sự xuất hiện trong mã MSVC của họ và do đó thực hiện các chuyên môn mà tôi đã cung cấp ... :-( –

2

Kỳ diệu thay, thời gian gần đây tôi đang đọc "C++ Templates: Hướng dẫn hoàn chỉnh", và cuốn sách cuối cùng đánh dấu sau đây trên trang 111:

Một mẫu đối số mẫu phải có một lớp mẫu với các thông số mà chính xác phù hợp với các thông số của thông số mẫu mẫu mà nó thay thế.Các đối số mẫu mặc định của đối số mẫu khuôn mẫu được bỏ qua (nhưng nếu tham số mẫu mẫu có đối số mặc định, chúng được xem xét trong quá trình tạo mẫu). Vì vậy, nếu cuốn sách được tin tưởng, ví dụ của bạn khi tham số mặc định không chuẩn được thêm vào std :: vector sẽ là hợp pháp - vì đối số mẫu mặc định của đối số mẫu mẫu bị bỏ qua.

Là một thử nghiệm thế giới thực, tôi biên soạn sau đây trong g ++ (thành công) và Visual Studio 2008 (thất bại trên các thông số không phù hợp):

template<typename T1, typename T2, typename T3 = float> 
class MyClass 
{ 
public: 
    T1 v1; 
    T2 v2; 
    T3 v3; 
}; 

template<template<typename T1, typename T2> class C> 
void f() 
{ 
    C<int,double> *c = new C<int,double>(); 
} 

int main() 
{ 
    f<MyClass>(); 
    return 0; 
} 
+2

Ý nghĩa của chúng với "Đối số mẫu mặc định của đối số mẫu mẫu bị bỏ qua" là mặc dù tham số có thể có đối số mặc định, đối số mặc định đó không phải là u sed và tham số tương ứng được tính như thể nó không có đối số mặc định. Vì vậy, nếu impl sẽ có một vector với 3 tham số, với tham số thứ 3 có đối số mặc định, thì truyền vector như một đối số mẫu mẫu giống như đối số mặc định đó không có. –

+0

Tôi đã cố gắng biên dịch ví dụ với g ++ 4.4.1 - nó từ chối, trong khi g ++ 4.1 chấp nhận mã. Điều này có vẻ như đó là một lỗi trong GCC. –

+0

Cảm ơn bạn đã làm rõ về đoạn văn đó - tôi đã diễn dịch nó một chút khác biệt. Tôi đã biên soạn trên 4.1 (một máy ảo Fedora cũ hơn mà tôi đã đá xung quanh). – csj

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