Le C++ définit les fonctions de formatage du temps en termes de strftime
ce qui nécessite un struct tm
l'enregistrement du "temps décomposé". Cependant, les langages C et C++03 ne fournissent pas de moyen sûr pour obtenir un tel enregistrement ; il n'y a qu'un seul maître. struct tm
pour l'ensemble du programme.
En C++03, cela était plus ou moins acceptable, car le langage ne prenait pas en charge le multithreading ; il ne faisait que supporter les plates-formes supportant le multithreading, qui fournissaient alors des facilités comme POSIX localtime_r
.
C++11 définit également de nouveaux utilitaires temporels, qui s'interfacent avec l'interface non brisée de l'outil de gestion du temps. time_t
type, qui est ce qui serait utilisé pour réinitialiser le global struct tm
. Mais l'obtention d'un time_t
n'est pas le problème.
Est-ce que j'ai raté quelque chose ou est-ce que cette tâche nécessite toujours de s'appuyer sur POSIX ?
EDIT : Voici un code de contournement. Il permet de maintenir la compatibilité avec les environnements multithreads qui offrent ::localtime_r
et les environnements monofilaires qui ne fournissent que std::localtime
. Il peut facilement être adapté pour vérifier d'autres fonctions, telles que posix::localtime_r
o ::localtime_s
ou ce que vous voulez.
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 ); }