2008-08-25 22 views
70

C++ 0x có bí danh mẫu (đôi khi được gọi là mẫu typedef). Xem here. Thông số kỹ thuật hiện tại của C++ thì không.Template typedefs - Công việc của bạn là gì?

Bạn thích sử dụng công việc gì? Đối tượng vùng chứa hoặc Macro? Bạn có cảm thấy nó đáng giá không?

+3

GOTW đã xử lý chủ đề này cách đây một thời gian: http://www.gotw.ca/gotw/079.htm –

Trả lời

102

Bạn thích sử dụng làm công việc gì? Đối tượng vùng chứa hoặc Macro? Bạn có cảm thấy nó đáng giá không?

Cách kinh điển là sử dụng một metafunction như vậy:

template <typename T> 
struct my_string_map { 
    typedef std::map<std::string, T> type; 
}; 

// Invoke: 

my_string_map<int>::type my_str_int_map; 

này cũng được sử dụng trong STL (allocator::rebind<U>) và trong nhiều thư viện bao gồm Boost. Chúng tôi sử dụng nó rộng rãi trong một bioinformatical library.

Nó cồng kềnh, nhưng đó là lựa chọn thay thế tốt nhất 99% thời gian. Sử dụng các macro ở đây không đáng giá nhiều nhược điểm.

(EDIT:. Tôi đã sửa đổi mã để phản ánh Boost/ước STL như chỉ ra bởi Daniel trong bình luận của ông)

+3

Nếu bạn sử dụng 'loại' thay vì 'Loại' (hoặc ngoài ra), điều này sẽ hoạt động tốt hơn với Boost.MPL. Điều này có thể hữu ích, vì vậy tôi nghĩ đó là một quy ước tốt để khuyến khích. –

+0

là điều này thực sự được gọi là một metafunction? tôi nghi ngờ nó. –

+5

@ Zenikoder: Hoàn toàn hợp lý để gọi nó là một sự thay thế và hầu hết các chuyên gia lập trình meta C++ làm như vậy (ví dụ: người Tăng cường). Không tồn tại một định nghĩa khắt khe nào nhưng cá nhân tôi gọi mọi thứ là một sự thay đổi, tại thời gian biên dịch, tạo ra một hằng số kiểu hoặc thời gian biên dịch cho một số đầu vào. Đó là, bất kỳ ánh xạ nào từ đầu vào đến đầu ra tại thời gian biên dịch. Tôi không biết rằng bất kỳ định nghĩa nào được chấp nhận rộng rãi hơn hoặc được chấp nhận rộng rãi hơn đều tồn tại. Cuối cùng, tôi có thể hỏi tại sao bạn phản đối việc sử dụng thuật ngữ này không? –

10
template <typename T> 
struct my_string_map : public std::map<std::string,T> 
{ 
}; 

Bạn không nên kế thừa từ các lớp học mà không làm có một destructor ảo. Nó liên quan đến destructors trong các lớp học có nguồn gốc không được gọi là khi họ nên được và bạn có thể kết thúc với bộ nhớ unallocated.

Điều đó đang được nói rằng bạn có thể ***** có thể ***** tránh xa nó trong ví dụ trên vì bạn không thêm bất kỳ dữ liệu nào khác vào loại có nguồn gốc của bạn. Lưu ý rằng đây không phải là một sự chứng thực. Tôi vẫn khuyên bạn đừng làm điều đó. Thực tế là bạn có thể làm điều đó không có nghĩa là bạn nên.

CHỈNH SỬA: Có, đây là câu trả lời cho bài đăng của ShaChris23. Tôi có lẽ đã bỏ lỡ điều gì đó vì nó xuất hiện phía trên thông điệp của anh ấy/cô ấy thay vì dưới đây.

+3

là điều này có nghĩa là trả lời bài đăng của ShaChris23? –

+0

Đây không phải là diễn đàn, bài đăng không xuất hiện theo thứ tự thời gian. Thông thường, đây sẽ là một bình luận. Bạn không thể, vì vậy có lẽ một câu trả lời của cộng đồng wiki sẽ làm. Dù bằng cách nào, câu hỏi là khá cũ. – GManNickG

+4

Tôi nhận thấy rằng nó khá cũ, nhưng tôi nghĩ rằng đó là một điều tốt để đảm bảo rằng nó không khuyến khích thực hành không chính xác. ttyl – xghost

0

Đôi khi bạn chỉ có thể viết một cách rõ ràng typedefs không được mô tả cho tất cả các loại cần thiết. Nếu lớp cơ sở là templated trên nhiều mẫu args với chỉ có một loại mong muốn được typedefed bạn có thể kế thừa một lớp học chuyên biệt với typedef có hiệu quả bao gồm trong tên lớp kế thừa. Cách tiếp cận này ít trừu tượng hơn so với cách tiếp cận metafunction.

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