2014-07-23 12 views
36

Rõ ràng, nhập bí danh và bí danh loại templated tương đương ngữ nghĩa với typedef và phần mở rộng của typedefs để hỗ trợ mẫu. Cách tạo cú pháp mới với từ khóa using được tạo cho các từ khóa này thay vì sử dụng typedef cho phần mở rộng đầu tiên và một số cú pháp với từ typedef.Tại sao loại bí danh trong C++ sử dụng 'using' thay vì 'typedef' trong cú pháp của chúng?

LƯU Ý: Đây không phải là bản sao của câu hỏi "khác biệt giữa sử dụng và typedef". Tôi biết rằng using tạo lợi thế cho việc xác định họ là typedef s. Điều tôi đang hỏi là tại sao những người tiêu chuẩn quyết định sử dụng tiện ích mở rộng này sử dụng từ khóa using thay vì từ khóa typedef. Điều này có vẻ như nó chỉ thêm nhầm lẫn trong ngôn ngữ.

+3

@Cyber, không phải vậy. Tôi biết rằng 'using' cho lợi thế của việc xác định một họ typedefs. Những gì tôi hỏi là tại sao những người tiêu chuẩn quyết định mở rộng này bằng cách sử dụng từ khóa 'using' thay vì từ khóa' typedef'. Điều này có vẻ như nó chỉ thêm nhầm lẫn trong ngôn ngữ. – tohava

+1

Có thể điều này liên quan đến các vấn đề được đề cập trong N1406 và cách N1499 giải quyết chúng. Giải pháp được phản ánh trong cú pháp: các bí danh mẫu không * xác định loại *, vì mẫu typedef sẽ đề xuất và phản đối đề xuất ban đầu của các mẫu typedef cho phép chuyên môn hóa (trong một phiên bản của nó). – dyp

+0

TL; DR vì typedef là một hack không thể đọc được khủng khiếp và có một cơ hội để thay thế nó bằng một cú pháp sạch hơn, nhẹ nhàng hơn. –

Trả lời

27

Những gì bạn đề xuất thực sự được đề xuất trở lại vào năm 2002 trong tài liệu N1406 bởi Herb Sutter. Nó sẽ cho phép, ví dụ, để viết:

template<typename T> typedef X<T,int> Xi; 

Điều này sau đó được sửa đổi trong N1449 bởi Gabriel Dos Reis và Mat Marcus. Họ áp dụng cú pháp using, và lưu ý những điều sau:

Lưu ý rằng chúng tôi đặc biệt tránh thuật ngữ “typedef mẫu” và giới thiệu cú pháp mới liên quan đến cặp “sử dụng” và “=” để giúp tránh nhầm lẫn: chúng tôi không xác định bất kỳ loại nào ở đây, chúng tôi đang giới thiệu một từ đồng nghĩa (tức là bí danh) cho một trừu tượng của một loại-id (tức là loại biểu thức) liên quan đến tham số mẫu.

Họ cũng trạng thái:

Hai cuộc thăm dò rơm đã được đưa về cú pháp. Một đa số mạnh đã bỏ phiếu để tránh cú pháp mẫu typedef, ủng hộ cú pháp “=”. Một cuộc bỏ phiếu thứ hai cho thấy sở thích mạnh mẽ đối với từ khóa "đang sử dụng" thay vì một từ như "bí danh" hoặc sự vắng mặt của bất kỳ từ khóa nào trong phiên bản dự thảo của đề xuất này. Động lực để sử dụng bất kỳ từ khóa nào bắt nguồn từ phần mong muốn sử dụng một cú pháp có thể tương thích với hướng răng cưa không phải mẫu được nêu ngắn gọn ở trên.

Cú pháp này sau đó được chấp nhận trong đề xuất cuối cùng N2258 bởi Gabriel Dos Reis và Bjarne Stroustrup.

+1

Bạn cũng có thể đề cập rằng đã có một cuộc thảo luận về ngữ nghĩa của các mẫu bí danh, N1406/2.2 "Lựa chọn chính: Chuyên môn so với mọi thứ khác". 'Using =' phản ánh ngữ nghĩa ở cấp độ cú pháp. – dyp

+0

Mẫu * là * một loại tham số. Bản thân Stroustroup thậm chí đã tuyên bố rằng trong một bài báo vào năm 1989 [https://www.usenix.org/legacy/publications/compsystems/1989/win_stroustrup.pdf]. Vì vậy, tôi sẽ lập luận rằng nó * là * tạo ra một loại mới hoặc gia đình các loại. Nhưng, tôi thực sự thích cú pháp mới, vì vậy tôi không phàn nàn gì nhiều hơn tôi thường phàn nàn về C++ bị quá phức tạp. – jtchitty

43

Đây là những gì Bjarne Stroustrup nói về việc tại sao họ giới thiệu using thay vì mở rộng typedef: "tên tiếp theo những gì nó đề cập đến"

Từ khóa sử dụng được sử dụng để có được một ký hiệu tuyến tính Chúng tôi đã thử với giải pháp typedef thông thường và phức tạp, nhưng không bao giờ quản lý để có được giải pháp hoàn chỉnh và mạch lạc cho đến khi chúng tôi giải quyết theo cú pháp ít mơ hồ hơn.

Ông cũng tuyên bố rằng anh thích cú pháp này cũng nhiều hơn cho typedefs thông thường:

Ngoài việc là quan trọng trong việc kết nối với các mẫu, loại bí danh cũng có thể được sử dụng như một khác nhau (và IMO tốt hơn) cú pháp để bí danh kiểu thông thường:

using PF = void (*)(double); 

Ông là khá chính xác ở đây, điều này dường như rất sạch sẽ. Ngược lại một typedef sẽ vô cùng phức tạp với tên là đâu đó ở giữa:

typedef void(*PF)(double); 

Dưới đây là một explanation (xem trang 4) từ đề xuất của họ mà thậm chí còn sâu sắc hơn:

nó đã được đề nghị (lại) sử dụng từ khoá typedef - như thực hiện trong giấy [4] - để giới thiệu mẫu bí danh:

template<class T> 
typedef std::vector<T,MyAllocator<T>> Vec; 

đó ký hiệu có lợi thế của việc sử dụng một chìa khóa từ đã được biết đến để giới thiệu một bí danh loại. Tuy nhiên, nó cũng hiển thị một số nhược điểm trong đó sự nhầm lẫn của việc sử dụng một từ khóa được biết đến để giới thiệu một bí danh cho một loại tên trong một bối cảnh mà bí danh không chỉ định một loại, nhưng một mẫu; Veckhông phải là bí danh cho một loại và không được sử dụng cho tên đã nhập. Tên Vec là tên cho họ std::vector<*,MyAllocator<*>> - trong đó dấu hoa thị là trình giữ chỗ cho tên loại. Do đó, chúng tôi không đề xuất cú pháp "typedef".

template<class T> 
using Vec = std::vector<T,MyAllocator<T>>; 

có thể được đọc/hiểu là: từ bây giờ trở đi, tôi sẽ sử dụng Vect<T> như một từ đồng nghĩa với std::vector<T,MyAllocator<T>>. Với việc đọc đó, cú pháp mới cho răng cưa có vẻ hợp lý.

Vì vậy, ông đã cơ bản hai điểm ở đây:

  1. Mẫu using trở thành một gia đình các loại, không phải là một loại, vì vậy typedef là "sai"
  2. using có thể được đọc gần như là một tiếng anh câu
+3

Tôi đồng ý với anh ta về điểm cuối cùng ... Tôi muốn nói 'using' nên đến để thay thế typedefs. Cú pháp ít rõ ràng hơn nhiều. – ApproachingDarknessFish

+0

Chỉ để so sánh, bạn có thể hiển thị những gì một typedef sẽ giống như ví dụ 'void (*) (double)' của bạn. :) – jalf

+0

@jalf: Ý tưởng hay, cảm ơn. – gexicide

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