BOOSTを使えと言う人もいると思います。したがって、BOOSTに依存しないソリューションを提供するために:
私は頻繁に同じ問題に遭遇したので、あきらめて、ブランドの%llu
orなどの代わりに %s にフィードする独自のヘルパー マクロを作成しまし%lu
た。また、適切なフォーマット文字列の設計を維持し、より優れた (そしてより一貫性のある) 16 進数とポインターの出力を提供するのに役立つこともわかりました。2 つの注意事項があります。
追加の書式設定パラメーター (左右の位置合わせ、パディングなど) を簡単に組み合わせることはできませんが、実際にはLU
マクロでもそれを行うことはできません。
この方法では、文字列の書式設定と印刷のタスクに追加のオーバーヘッドが追加されます。ただし、私はパフォーマンスが重要なアプリを作成していますが、Microsoft の Visual C++ デバッグ ビルド (すべての内部検証と破損チェックのため、通常よりもヒープ メモリの割り当てと解放に約 200 倍の時間がかかります) を除いて、それが問題であることに気づいていません。
比較は次のとおりです。
printf( "Value1: " LU ", Value2: " LU, somevar1, somevar2 );
対。
printf( "Value1: %s, Value2: %s", cStrDec(somevar1), cStrDec(somevar2) );
それを機能させるために、次のような一連のマクロとテンプレートを使用しました。
#define cStrHex( value ) StrHex ( value ).c_str()
#define cStrDec( value ) StrDecimal( value ).c_str()
std::string StrDecimal( const uint64_t& src )
{
return StrFormat( "%u%u", uint32_t(src>>32), uint32_t(src) );
}
std::string StrDecimal( const int64_t& src )
{
return StrFormat( "%d%u", uint32_t(src>>32), uint32_t(src) );
}
std::string StrDecimal( const uint32_t& src )
{
return StrFormat( "%u", src );
}
std::string StrDecimal( const int32_t& src )
{
return StrFormat( "%d", src );
}
std::string StrHex( const uint64_t& src, const char* sep="_" )
{
return StrFormat( "0x%08x%s%08x", uint32_t(src>>32), sep, uint32_t(src) );
}
std::string StrHex( const int64_t& src, const char* sep="_" )
{
return StrFormat( "0x%08x%s%08x", uint32_t(src>>32), sep, uint32_t(src) );
}
// Repeat implementations for int32_t, int16_t, int8_t, etc.
// I also did versions for 128-bit and 256-bit SIMD types, since I use those.
// [...]
私の文字列フォーマット関数は、次のような std::string に直接フォーマットする現在推奨されている方法に基づいています。
std::string StrFormatV( const char* fmt, va_list list )
{
#ifdef _MSC_VER
int destSize = _vscprintf( fmt, list );
#else
va_list l2;
va_copy(l2, list);
int destSize = vsnprintf( nullptr, 0, fmt, l2 );
va_end(l2);
#endif
std::string result;
result.resize( destSize );
if (destSize!=0)
vsnprintf( &result[0], destSize+1, fmt, list );
return result;
}
std::string StrFormat( const char* fmt, ... )
{
va_list list;
va_start( list, fmt );
std::string result = StrFormatV( fmt, list );
va_end( list );
return *this;
}