Другие указали на ошибку с обычными объектами.
template<typename T>
Debug& operator<<(T const& value)
{
if ( m_output )
{
std::cout << value;
}
return *this;
}
Но вам также нужен способ вывода std :: endl и других манипуляторов.Поскольку шаблон выше не будет обрабатывать их правильно.Для этого вам понадобится оператор, который обрабатывает функторы, которые управляют потоками (то есть всеми iomanipators (например, std :: endl)).
// Use a typedef to make the code readable.
// This is a function pointer that takes a stream as input and returns the stream.
// This covers functions like std::endl
typedef std::ostream& (*STRFUNC)(std::ostream&);
D& operator<<(STRFUNC func) // Inside the class
{
if ( m_output )
{
// Apply the function
func(std::cout);
}
// But return the debug object
return *this;
}
Реализация, которая обрабатывает как нормальные, так и широкие потоки:
#include <iostream>
#if defined(_DEBUG)
#define DEBUG_LOG_TEST_CONDITION output
#define DEBUG_LOG_DEBUG_TEST_LEVEL(v) (v) <= DebugCake::DebugLevel
#else
#define DEBUG_LOG_TEST_CONDITION false
#define DEBUG_LOG_DEBUG_TEST_LEVEL(v) false
#endif
template<typename C,typename T = std::char_traits<C> >
struct DInfo
{
typedef std::basic_ostream<C,T>& (*StrFunc)(std::basic_ostream<C,T>&);
static std::basic_ostream<C,T>& getDefault();
};
struct DebugCake
{
static int DebugLevel;
};
template<typename C,typename T = std::char_traits<C> >
struct D
{
D(int level)
:stream(DInfo<C,T>::getDefault())
,output( DEBUG_LOG_DEBUG_TEST_LEVEL(level) )
{}
D(int level, std::basic_ostream<C,T>& s)
:stream(s)
,output( DEBUG_LOG_DEBUG_TEST_LEVEL(level) )
{}
template<typename V>
D& operator<<(V const& value)
{
// In release this is optimised away as it is always false
if (DEBUG_LOG_TEST_CONDITION)
{
stream << value;
}
return *this;
}
D& operator<<(typename DInfo<C,T>::StrFunc func)
{
// In release this is optimised away as it is always false
if (DEBUG_LOG_TEST_CONDITION)
{
func(stream);
}
return *this;
}
private:
std::basic_ostream<C,T>& stream;
bool output;
};
template<>
std::ostream& DInfo<char,std::char_traits<char> >::getDefault()
{return std::cout; }
template<>
std::wostream& DInfo<wchar_t,std::char_traits<wchar_t> >::getDefault()
{return std::wcout; }
typedef D<char> Debug;
typedef D<wchar_t> WDebug;
int DebugCake::DebugLevel = 4;
int main()
{
Debug debug(1);
debug << "Plop" << std::endl;
WDebug debugWide(2);
debugWide << L"WIDE" << std::endl;
}