自定义类 ostringstream 输出错误
Custom class ostringstream output error
我不知道为什么会出错,但我只是想在endl中添加一些"类似"的东西,以便我可以将ostringstream中的内容扔到我们的调试器中。 我有以下几点:
class debug_stream_info
{
public:
debug_stream_info(int errorLine, char *errorFile, int level)
:m_errorLine(errorLine), m_errorFile(errorFile), m_logLevel(level)
{
}
friend std::basic_ostringstream<char>& operator<<(std::basic_ostringstream<char>& os, debug_stream_info& debug_info);
private:
int m_errorLine;
std::string m_errorFile;
int m_logLevel;
};
std::basic_ostringstream<char>& operator<<(std::basic_ostringstream<char>& os, debug_stream_info& debug_info)
{
// Write the stream's contents to cpu_debug
// Deleted custom logging function. No errors here though
// Clear the stream for re-use.
os.str("");
os.seekp(0);
return os;
}
int main(int argc, char** argv)
{
std::ostringstream myout;
myout << "hey there" << " and some more " << "Numbers!!: " << 435 << 54.2 << " that's good for numbers" << debug_stream_info(__LINE__, __FILE__, LOG_LEVEL);
return 0;
}
我得到的错误是:main中的行error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'debug_stream_info' (or there is no acceptable conversion)
。 这是在VS2008上。
我包括 sstream、iostream 等,并正确设置了命名空间。 我没有收到其他错误。 我什至尝试用 ostringstream
替换所有出现的 basic_ostream
,没有区别(我稍后会有一个w_char
版本,但我希望简单的案例首先起作用(。 我在上面的行上制作了对象,然后在行上传递了一个完全构造的对象,错误完全相同。 我已经将第二个参数的签名更改为const
,也没有更改。
关于我在这里做错了什么的任何想法?
编辑:由于每个响应似乎都想把它放在那里,所以我不能使用 std::ostream,因为我希望它仅适用于std::ostringstream
(和std::basic_ostringstream
(,而不是任何类型的输出流。 此外,该函数无论如何都不会使用 ostream 编译,因为我使用的是 os.str()
方法,该方法不在 ostream 中,只有子类。
代码的真正问题是你重载了std::ostringstream
而不是std::ostream
。所以如果你写这个,你的代码就会工作:
debug_stream_info info(/** blah blah**/);
std::ostringstream oss;
oss << info ; //OK
但是,这将不起作用:
oss << 1 << info; //ERROR
这是编译错误,因为表达式oss<<1
返回一个类型为 std::ostream&
的对象,该对象没有将debug_stream_info
作为第二个参数的重载。这意味着如果您使用强制转换为:
static_cast<std::ostringstream&>(oss << 1) << info; //OK
那么这应该再次起作用。
所以解决方案是重载std::ostream
,而不是std::basic_ostringstream
。
此外,第二个参数应为 const &
。这也是您的代码的问题。
所以写这个:
std::ostream& operator<<(std::ostream&, debug_stream_info const &);
//^^^^^^^ note this
应const &
第二个参数,以便可以将临时对象写入流。
debug_stream_info(__LINE__, __FILE__, LOG_LEVEL);
正在创建未命名的对象,该对象不返回任何内容,因此错误
#include <iostream>
#include <cstdio>
#include <sstream>
using namespace std;
class debug_stream_info
{
public:
debug_stream_info(int errorLine, char *errorFile, int level)
:m_errorLine(errorLine), m_errorFile(errorFile), m_logLevel(level)
{
}
friend std::basic_ostringstream<char>& operator<<(std::basic_ostringstream<char>& os, debug_stream_info& debug_info);
std::ostringstream& fun(std::ostringstream& os)
{
os<<"Ashish"<<endl;
return os;
}
private:
int m_errorLine;
std::string m_errorFile;
int m_logLevel;
};
std::basic_ostringstream<char>& operator<<(std::basic_ostringstream<char>& os, debug_stream_info& debug_info)
{
// Write the stream's contents to cpu_debug
// Deleted custom logging function. No errors here though
// Clear the stream for re-use.
// os.str("");
// os.seekp(0);
return os;
}
int main(int argc, char** argv)
{
std::ostringstream myout, test;
myout << "hey there" << " and some more " << "Numbers!!: " << 435 << 54.2 << " that's good for numbers"
<< debug_stream_info(1, "/home/ashish/test", 1).fun(test);
return 0;
}
Nawaz已经非常清楚地解释了为什么你会得到错误。 这在这种情况下,通常的解决方案是定义自己的流类型,不相关到std::istream
. 大致如下:
class DebugStream
{
std::ostringstring* collector;
public:
template <typename T>
DebugStream& operator<<( T const& value )
{
if ( collector != NULL ) {
*collector << value;
}
return *this;
}
};
这有无限的变化;在你的情况下,你可以添加一个您的类型的非模板成员函数;更有可能的是,您会添加一个采用相同参数的构造函数:
DebugStream( int lineNumber, std::string const& filename, int logLevel )
: collector( isActive( logLevel ) ? new std::ostringstream : NULL )
{
// Initial insertion of lineNumber, filename, timestamp...
}
您还可以添加一个析构函数,该析构函数以原子方式刷新收集的数据到文件(或发送电子邮件,或将其写入系统日志,或随便(。 (对此要非常小心。 你不希望有例外从析构函数转义,即使日志记录失败也是如此。
最后,您可能希望使用自定义 streambuf,而不是 stringstream
. 假设一个保持分配的缓冲区远离一个实例到下一个。 如果你这样做,而不是new
每次流,您可能会从表中选取一个实例,索引由日志级别(并从配置文件初始化(。
- 显示错误输出的简单数组排序程序
- Dijkstra 中的错误输出
- 自定义runtime_error,如果我在 #what 中使用#c_str(),则错误输出始终为空
- 流字符串错误输出
- C++ 异常处理错误输出
- C ++中的错误输出,i = 65530,当我们打印i的值时,它给出-6状态65530
- SSE和iostream:浮点类型的错误输出
- C++将 popen 错误输出读取为字符串
- 部分透视/高斯消除 - 交换列而不是产生错误输出的行
- C++,向量:获得包含 0 的错误输出
- 数组函数错误输出
- CC1plus 错误:输出文件名指定两次
- 字符串错误输出
- 子斯特的错误输出
- 对大量c++错误输出完全一无所知.我认为这与预定义的函数和迭代器有关
- 简单程序的错误输出
- XCode调试器lldb中断,没有错误输出,但程序运行良好
- std::string::append(std::string)错误输出
- 查看大错误输出的顶行
- 使用结构的错误输出