2009-04-12 18 views
48

Tôi luôn tự hỏi tại sao bạn không thể sử dụng các lớp được định nghĩa cục bộ làm các biến vị ngữ cho các thuật toán STL.Sử dụng các lớp địa phương với các thuật toán STL

Trong câu hỏi: Approaching STL algorithms, lambda, local classes and other approaches, BubbaT đề cập nói rằng 'Kể từ khi chuẩn C++ cấm loại địa phương được sử dụng như các đối số'

Ví dụ mã:

int main() { 
    int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 
    std::vector<int> v(array, array+10); 

    struct even : public std::unary_function<int,bool> 
    { 
     bool operator()(int x) { return !(x % 2); } 
    }; 
    std::remove_if(v.begin(), v.end(), even()); // error 
} 

Có ai biết nơi ở tiêu chuẩn là hạn chế? Lý do cho việc không cho phép các loại địa phương là gì?


EDIT: Kể từ C++ 11, nó là hợp pháp để sử dụng một loại địa phương như một mẫu đối số.

Trả lời

50

Nó bị cấm theo tiêu chuẩn C++ 98/03.

C++ 11 xóa giới hạn đó.

Để được hoàn chỉnh hơn:

Các hạn chế đối với loại có sử dụng như các thông số mẫu được liệt kê tại Điều 14.3.1 của C++ 03 (và C++ 98) tiêu chuẩn:

Loại địa phương, loại không có liên kết, loại không được đặt tên hoặc loại phức hợp từ bất kỳ loại nào không được sử dụng dưới dạng đối số mẫu cho thông số loại mẫu .

template <class T> class Y { /* ... */ }; 
void func() { 
     struct S { /* ... */ }; //local class 
     Y<S> y1; // error: local type used as template-argument 
     Y< S* > y2; // error: pointer to local type used as template-argument } 

Nguồn và biết thêm chi tiết: http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=420

Tóm lại, những hạn chế là một sai lầm mà có thể đã được cố định sớm hơn nếu tiêu chuẩn đã được phát triển nhanh hơn ...

Điều đó nói rằng ngày nay hầu hết các phiên bản mới nhất của trình biên dịch thông thường đều cho phép nó, cùng với việc cung cấp các biểu thức lambda.

+0

Tôi biết, nhưng tôi muốn biết nơi để xem liệu tôi có thể hiểu tại sao không. Bạn có một tham chiếu vào tiêu chuẩn? –

+0

Bạn đang đề cập đến 14.3.1.2, "đối số kiểu mẫu"? – greyfade

+0

Tôi đã thêm một số thông tin và liên kết có thể trợ giúp. Tóm lại, hạn chế là một sai lầm có thể nhanh chóng được khắc phục nếu tiêu chuẩn phát triển nhanh hơn ... – Klaim

5

Hạn chế sẽ bị xóa trong '0x, nhưng tôi không nghĩ rằng bạn sẽ sử dụng chúng rất nhiều. Và đó là vì C++ - 0x sẽ có lambdas! :)

int main() { 
    int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 
    std::vector<int> v(array, array+10); 

    std::remove_if(v.begin() 
       , v.end() 
       , [] (int x) -> bool { return !(x%2); }) 
} 

Cú pháp của tôi ở trên có thể không hoàn hảo, nhưng ý tưởng chung là ở đó.

+0

Tôi biết về lambdas. Trong thực tế, những gì tôi muốn đạt được là gần nhất có thể với tiêu chuẩn hiện hành. Loại giải pháp Java đề xuất. –

+0

Và theo cách nào đây là câu trả lời cho câu hỏi thực tế (hãy để một mình một giá trị 4 phiếu bầu)? –

+0

@ChristianRau:;) Tôi có thể thấy lý do tại sao bạn muốn nói điều này. Câu hỏi đặt ra là tại sao họ không được phép và dòng đầu tiên của câu trả lời giải quyết vấn đề này. nó đã bị loại bỏ vì vậy không phải là một lý do chính đáng để hạn chế. Vào thời điểm đó tôi nghĩ rõ ràng lambdas đáng nói đến. Bây giờ tất nhiên 3 năm sau lambdas nổi tiếng nên họ không còn tin tức nữa! –

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