Dưới đây tôi bỏ qua các không gian tên vì lợi ích của việc súc tích. duration
nằm trong không gian tên std::chrono
và ratio
nằm trong không gian tên std
.
Có hai cách tốt để luôn đảm bảo rằng ratio
của bạn được giảm xuống các điều kiện thấp nhất mà không phải tự mình làm số học. Đầu tiên là khá trực tiếp:
Việc xây dựng trực tiếp
Nếu bạn chỉ muốn nhảy thẳng đến microfortnights
, nhưng mà không cần phải tìm ra rằng phần giảm 86.400 * 14/1.000.000 là 756/625, chỉ cần thêm ::type
sau ratio
:
using microfortnights = duration<long, ratio<86400*14, 1000000>::type>;
các lồng nhau type
của mỗi ratio<N, D>
là một ratio<Nr, Dr>
nơi Nr/Dr
là giảm phần N/D
. Nếu N/D
đã bị giảm, thì ratio<N, D>::type
là cùng loại với ratio<N, D>
.Trên thực tế, đã có tôi đã tìm ra rằng 756/625 là giảm phần đúng, nhưng chỉ là hoang tưởng trong suy nghĩ nó có thể có thể giảm hơn nữa, tôi có thể viết:
using microfortnights = duration<long, ratio<756, 625>::type>;
Vì vậy, nếu bạn có bất kỳ nghi ngờ rằng bạn ratio
được thể hiện bằng thuật ngữ thấp nhất hoặc không muốn bị làm phiền với việc kiểm tra, bạn luôn có thể thêm ::type
vào loại ratio
của mình để đảm bảo.
Việc xây dựng verbose
đơn vị thời gian thời gian Tuỳ chỉnh thường bật lên như là một phần của một gia đình. Và nó thường thuận tiện để có toàn bộ gia đình có sẵn cho mã của bạn. Ví dụ: microfortnights
rõ ràng là liên quan đến fortnights
, lần lượt có liên quan đến weeks
, có nguồn gốc từ days
, có nguồn gốc từ hours
(hoặc từ seconds
nếu bạn thích).
Bằng cách xây dựng một gia đình mỗi lần, bạn không chỉ làm cho toàn bộ gia đình có sẵn, bạn cũng giảm nguy cơ lỗi bằng cách liên kết một thành viên gia đình với thành viên khác với chuyển đổi đơn giản nhất có thể. Ngoài ra, việc sử dụng std::ratio_multiply
và std::ratio_divide
, thay vì nhân chữ cái cũng có nghĩa là bạn không phải giữ thêm ::type
ở khắp mọi nơi để đảm bảo rằng bạn giữ số ratio
ở mức thấp nhất.
Ví dụ:
using days = duration<long, ratio_multiply<hours::period, ratio<24>>>;
ratio_multiply
là một typedef tên đến kết quả của phép nhân đã giảm xuống còn từ ngữ thấp nhất. Vì vậy, ở trên là chính xác cùng loại như:
using days = duration<long, ratio<86400>>;
Bạn thậm chí có thể có cả hai định nghĩa trong các đơn vị dịch tương tự, và bạn sẽ không nhận được một lỗi tái định nghĩa. Trong mọi trường hợp, bây giờ bạn có thể nói:
using weeks = duration<long, ratio_multiply<days::period, ratio<7>>>;
using fortnights = duration<long, ratio_multiply<weeks::period, ratio<2>>>;
using microfortnights = duration<long, ratio_multiply<fortnights::period, micro>>;
Và chúng tôi đã kết thúc với một typedef tên cho microfortnights
đó là chính xác cùng loại như trong xây dựng trực tiếp của chúng tôi, nhưng qua một loạt các đơn giản hơn nhiều chuyển đổi. Chúng tôi vẫn không phải bận tâm với việc giảm phân số xuống các điều kiện thấp nhất, và bây giờ chúng tôi có một số đơn vị hữu ích thay vì chỉ một.
Cũng lưu ý việc sử dụng std::micro
thay cho std::ratio<1, 1000000>
. Đây là một nơi khác để tránh các lỗi bất cẩn. Nó rất dễ dàng (ít nhất là đối với tôi) để nhập nhầm (và đọc sai) số lượng số 0.
Bạn có thể thay đổi cụm từ câu hỏi thành 'std :: ratio' thay thế không? Dường như chủ đề bao quát có rất ít việc phải làm với 'chrono' ngoại trừ ví dụ đã chọn? – sehe
Bạn có một điểm tốt. Tuy nhiên tôi muốn tập trung vào 'thời lượng', nếu không tôi sợ khán giả sẽ không thấy ứng dụng thực tế của 'tỷ lệ'. Tôi đã thêm 'tỷ lệ' vào tiêu đề để các tìm kiếm cho' tỷ lệ' sẽ dễ dàng tìm thấy Q/A này hơn. –
Hehe. 1 cho anyways thiết lập. (Trớ trêu thay, phải mất một thời gian để thấy rằng điều này thực sự có liên quan hơn là chỉ để tạo ra _microfortnight_ khó hiểu "đúng" :)) – sehe