目的
以下の4つの特徴を合わせ持つ関数を設計する。
以下の4つの特徴を合わせ持つ関数を設計する。
- 書式指定が簡潔(printf)
- 型セーフかつ拡張性がある(std::cout)
- Visual StudioやDebugViewに出力できる(OutputDebugString)
- Visual Studioの「出力」ウィンドウ内をダブルクリックするとソースコードの指定行にジャンプする
桁数など細かいしても簡単。
int w = 1024;
int h = 768;
DLOG("%04d, %04d") % w % h;
文字列だって簡単。
std::string fname = "test.txt";
DLOG("%s") % fname.c_str();
ただし、他の演算子を含む場合は、%演算子の優先順が低いため括弧()が必要になる。
DLOG("%d") % (1+5);
std::coutと同様の機能は全て備えている!cv::Mat_等の出力も簡単。
#include<opencv2/opencv.hpp>
cv::Mat mat = (cv::Mat_<double>(3, 1) <<
1.0, 2.0, 3.0,
1.0, 2.0, 3.0,
1.0, 2.0, 3.0
);
DLOG("\n%s") % mat;
上記の4つの例の出力例。
.\Test.cpp ( 10) : 12345 TestClass::testFunc 1024, 768 .\Test.cpp ( 20) : 12345 TestClass::testFunc test.txt .\Test.cpp ( 30) : 12345 TestClass::testFunc .\Test.cpp ( 40) : 12345 TestClass::testFunc [1 2, 3; 1, 2, 3; 1, 2, 3]フォーマットはこの通り。「:」までがVisual Studio特有のフォーマットでこのように出力すると、出力ウィンドウ内の出力行をクリックすると、ソースコードの対応する行にジャンプするようになっている。
ファイル名 (行番) :スレッド番号 クラス名::関数名 出力
ソースコード
※以下は、このサイトに書かれているかなりの部分を流量している。http://reindeer7125.blog129.fc2.com/blog-entry-6.html
#include <boost/format.hpp>
#include <string>
#include <iosfwd>
#include <boost/iostreams/categories.hpp>
#include <boost/iostreams/stream.hpp>
#include <windows.h>
#define DLOG dbgout() << (boost::format("%-20s(%4d) : %d %s ") \
% __FILE__ % __LINE__ % GetCurrentThreadId() % __FUNCTION__) << boost::format
namespace detail{
inline void output_debug_string( const char *s){
::OutputDebugStringA( s);
}
inline void output_debug_string( const wchar_t *s){
::OutputDebugStringW( s);
}
template<class _Ch>
class dbgout_sink
{
public:
typedef _Ch char_type;
typedef boost::iostreams::sink_tag category;
std::streamsize write( const char_type *s, std::streamsize n){
std::basic_string<char_type> buf( s, n );
buf += '\n';
output_debug_string(buf.c_str());
return n;
}
};
template<class _Ch>
class basic_dbgout : public boost::iostreams::stream<detail::dbgout_sink<_Ch> >
{
public:
basic_dbgout(): boost::iostreams::stream<detail::dbgout_sink<_Ch> >(dout_sink){}
private:
detail::dbgout_sink<_Ch> dout_sink;
};
}//namespace detail
typedef detail::basic_dbgout<char> dbgout;
typedef detail::basic_dbgout<wchar_t> wdbgout;
typedef detail::basic_dbgout<TCHAR> tdbgout;