我有以下课程:
namespace {
class MimeLogger : public std::ostringstream
{
public:
MimeLogger()
{}
~MimeLogger()
{
LOGEVENT( logModuleWSE, logEventDebug, logMsgWSETrace1, str() );
}
};
}
当我这样做时:
MimeLogger() << "Hello " << "World";
第一个"Hello "
字符串被视为void*
。如果我调试代码,"Hello "
将传递到std::basic_ostream::operator<< (void const*)
并打印为指针值,而不是字符串。第二个字符串"World"
被正确传递到全局重载&lt;&lt;采用char const*
。
我希望&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;运算符解决相同的重载,但这不会发生。有人可以解释,也许可以提出解决方案吗?
提前致谢。
我忽略了提到我坚持使用C ++ 03,但我很高兴有些人同时介绍了C ++ 03和C ++ 11。
答案 0 :(得分:7)
C ++ 03:对于表达式MimeLogger() << "Hello "
,模板函数
template <typename charT, class traits>
std::basic_ostream<charT, traits>& std::operator<< (
std::basic_ostream<charT, traits>& os,
const char* cstr);
在重载解析期间不考虑,因为临时MimeLogger()
可能未绑定到非const引用。成员函数重载没有此问题,因为隐式参数的规则允许绑定到临时。
如果您可以使用支持C ++ 11 rvalue-references的编译器,这应该可以按预期工作,因为C ++ 11库提供了额外的重载
template <typename charT, class traits, typename T>
std::basic_ostream<charT, traits>& std::operator<< (
std::basic_ostream<charT, traits>&& os,
const T& x ); // { os << x; return os; }
允许在<<
左侧使用临时流,就好像它们不是临时的一样。
(我确实尝试过使用g ++的测试程序,并且在没有-std = c ++ 0x的情况下获得了不同的结果。)
如果您不能使用C ++ 11友好编译器,将其添加到class MimeLogger
的公共部分是一种解决方法,可以使用C ++ 03执行您想要的操作:
template<typename T>
MimeLogger& operator<<(const T& x)
{
static_cast<std::ostringstream&>(*this) << x;
return *this;
}
using std::ostringstream::operator<<;
using声明确保MimeLogger
中也可以看到标准库中的成员重载。特别是,没有像std::endl
这样的操纵器不能与模板操作符一起使用,因为std::endl
本身就是一个函数模板,而且C ++的模板类型推导过多。但只要我们确定不隐藏使函数操纵器工作的ostream
成员(27.7.3.6.3),事情就好了。
namespace std {
template <typename charT, class traits>
class basic_ostream : /*...*/ {
public:
basic_ostream<charT, traits>& operator<<(
basic_ostream<charT,traits>& (*pf)(basic_ostream<charT,traits>&));
};
}
答案 1 :(得分:0)
如何使用std::ostringstream
的遏制?
class MimeLogger
{
private:
std::ostringstream oss_m;
public:
MimeLogger()
{
}
~MimeLogger()
{
std::cout << __FILE__ << "(" << __LINE__ << "):" << oss_m.str() << "\n";
}
template<typename Type>
MimeLogger& operator<<(const Type& t)
{
oss_m << t;
return *this;
}
};
void LogDemo()
{
MimeLogger logger;
logger << "Hello " << "World!!\n";
MimeLogger() << "Hello " << "StackOverflow!!\n";
}