Tôi đã làm việc trên bộ điều hợp lặp UTF-8. Theo đó, ý tôi là một bộ chuyển đổi biến một trình vòng lặp thành một char
hoặc unsigned char
trình tự thành một trình vòng lặp thành một char32_t
trình tự. Công việc của tôi ở đây được lấy cảm hứng từ trình vòng lặp này mà tôi tìm thấy trên mạng .
Tuy nhiên, khi tôi xem qua tiêu chuẩn khi tôi bắt đầu thực hiện, tôi đã nhận ra rằng: dường như không thể thực hiện một bộ chuyển đổi như vậy trong khi vẫn tuân thủ các yêu cầu mà C ++ đặt trên các trình vòng lặp.
Ví dụ: bạn có thể tạo một trình lặp UTF-8 thỏa mãn các yêu cầu của InputIterator không? Có, nhưng chỉ chừng nào trình lặp mà bạn được cung cấp không phải là Trình nhập liệu. Tại sao?
Bởi vì InputIterator yêu cầu khả năng hủy đăng ký cùng một trình vòng lặp nhiều lần. Bạn cũng có thể hủy đăng ký nhiều bản sao của trình vòng lặp đó, miễn là tất cả chúng đều so sánh bằng nhau.
Tất nhiên, việc hủy bỏ hội thảo một bộ điều hợp lặp UTF-8 đòi hỏi cả việc hủy bỏ hội nghị và có khả năng tăng trình lặp cơ sở. Và nếu iterator đó là InputIterator, thì bạn không thể lấy lại giá trị ban đầu sau khi bạn tăng nó. Và thực tế là các bản sao phải hoạt động có nghĩa là bạn không thể lưu trữ cục bộ một char32_t
giá trị đại diện cho giá trị được giải mã trước đó. Bạn có thể đã làm điều này:
auto it = ...
auto it2 = it; //Copies an empty `char32_t`.
*it; //Accesses base iterator, storing `it.ch`.
*it; //Doesn't access the base iterator; simply returns `it.ch`.
*it2; //Cannot access `it.ch`, so must access base iterator.
OK, tốt, vì vậy bạn không thể sử dụng InputIterators. Nhưng còn ForwardIterator thì sao? Có thể tạo bộ điều hợp ForwardIterator có thể điều chỉnh ForwardIterators qua chuỗi ký tự UTF-8 không?
Đó cũng là vấn đề, bởi vì hoạt động *it
được yêu cầu để sản xuất value_type&
hoặc const value_type&
. InputIterators có thể phun ra bất cứ thứ gì có thể chuyển đổi thành value_type
, nhưng a ForwardIterator
bắt buộc phải cung cấp một tham chiếu thực tế [Forward.iterators] /1.3:
if
X
là một iterator có thể thay đổi,reference
là một tham chiếu đếnT
; ifX
là một iterator không đổi,reference
là một tham chiếu đếnconst T
Việc truy vấn duy nhất ở đây là cho mọi trình vòng lặp như vậy mang theo một char32_t
, chỉ tồn tại để cung cấp lưu trữ cho tham chiếu đó. Và thậm chí sau đó, giá trị đó sẽ phải được cập nhật mỗi khi đối tượng lặp được tăng lên và hủy đăng ký. Điều này vô hiệu hóa tham chiếu cũ và tiêu chuẩn không cho phép rõ ràng rằng (việc vô hiệu chỉ có thể xảy ra khi một trình vòng lặp bị hủy hoặc nếu container nói như vậy).
Mã đã nói ở trên mà tôi tìm thấy trực tuyến không hợp lệ do điều này, vì nó trả về một uint32_t
(viết trước C ++ 11) theo giá trị chứ không phải là một tham chiếu thích hợp.
Có bất kỳ truy đòi ở đây? Tôi đã bỏ qua một cái gì đó trong tiêu chuẩn, hoặc một số kỹ thuật thực hiện mà tôi có thể sử dụng để bỏ qua những vấn đề này? Hoặc điều này chỉ đơn giản là không thể với từ ngữ hiện tại của tiêu chuẩn?
Lưu ý: điều kỳ lạ là dường như có thể viết một Bộ tạo đầu ra phù hợp cho chuyển đổi UTF-8. Đó là, một kiểu lấy char32_t
và ghi UTF-8 vào một char
hoặc unsigned char
Bộ tạo đầu ra.
ForwardIterator
này không phù hợp với bất kỳ loại trình vòng lặp proxy nào , chẳng hạn như những từvector<bool>
có thể thực hiện được . Có một bài báo nổi tiếng được viết vào năm 1999 bởi Herb Sutter đã giải thích lý do tại sao quyết tâm đó được đưa ra. Trong thời hiện đại, có một xu hướng suy nghĩ lại về vấn đề này. Tôi tìm thấy một bài được viết bởi Eric Niebler . Có thể có nhiều hơn; thậm chí có thể có một số được viết bởi chính Herb Sutter, trong một số đề xuất C ++.