C++ xác định chức năng định dạng thời gian theo điều khoản của strftime
, yêu cầu bản ghi "thời gian bị hỏng" struct tm
. Tuy nhiên, ngôn ngữ C và C++ 03 không cung cấp cách an toàn cho luồng để có được bản ghi như vậy; chỉ có một chủ struct tm
cho toàn bộ chương trình.C++ 11 thay thế cho localtime_r
Trong C++ 03, điều này ít nhiều là OK, bởi vì ngôn ngữ không hỗ trợ đa luồng; nó chỉ hỗ trợ các nền tảng hỗ trợ đa luồng, sau đó cung cấp các cơ sở như POSIX localtime_r
.
C++ 11 cũng định nghĩa các tiện ích thời gian mới, giao diện với các phi vỡ xuống time_t
loại, mà là gì sẽ được sử dụng để khởi tạo lại toàn cầu struct tm
. Nhưng lấy một số time_t
không phải là vấn đề.
Tôi có thiếu điều gì đó hoặc thực hiện tác vụ này vẫn yêu cầu sự phụ thuộc vào POSIX không?
EDIT: Đây là một số mã giải pháp. Nó duy trì khả năng tương thích với môi trường đa luồng cung cấp ::localtime_r
và môi trường một luồng chỉ cung cấp std::localtime
. Nó có thể dễ dàng được điều chỉnh để kiểm tra các chức năng khác, chẳng hạn như posix::localtime_r
hoặc ::localtime_s
hoặc những gì bạn có.
namespace query {
char localtime_r(...);
struct has_localtime_r
{ enum { value = sizeof localtime_r(std::declval< std::time_t * >(), std::declval< std::tm * >())
== sizeof(std::tm *) }; };
template< bool available > struct safest_localtime {
static std::tm *call(std::time_t const *t, std::tm *r)
{ return localtime_r(t, r); }
};
template<> struct safest_localtime<false> {
static std::tm *call(std::time_t const *t, std::tm *r)
{ return std::localtime(t); }
};
}
std::tm *localtime(std::time_t const *t, std::tm *r)
{ return query::safest_localtime<query::has_localtime_r::value>().call(t, r); }
Bạn không thể chỉ quấn 'localtime' trong một hàm sử dụng mutex? Hoặc một số hình thức trọng lượng nhẹ hơn của khóa? Tôi không thấy POSIX được yêu cầu ở đây như thế nào. –
@Nicol: Có, nhưng điều đó chỉ an toàn miễn là không ai khác cố gắng làm điều tương tự. Nói cách khác, nó hoạt động trong một chương trình, không phải trong một thư viện. – Potatoswatter
Nhưng sau đó họ sẽ gọi một chức năng không an toàn với luồng từ mã luồng, vì vậy họ sẽ có được những gì họ xứng đáng nhận được. Bạn chỉ có thể phơi bày một chức năng cho họ để sử dụng, và nếu họ sử dụng một tiêu chuẩn C thay vào đó, sau đó họ nhận được hành vi không xác định. –