【发布时间】:2016-10-30 17:01:38
【问题描述】:
我正在寻找一种同时写入文件和控制台的解决方案。我找到了一个不错的解决方案here。
由于我在 C++11 之前工作,因此我不得不对 Lightness Races in Orbit 中的代码进行一些小改动:
#include <iostream>
#include <fstream>
#include <string>
struct OutputAndConsole : std::ofstream
{
OutputAndConsole(const std::string& fileName)
: std::ofstream(fileName.c_str()) // constructor taking a string is C++11
, fileName(fileName)
{};
const std::string fileName;
};
template <typename T>
OutputAndConsole& operator<<(OutputAndConsole& strm, const T& var)
{
std::cout << var;
static_cast<std::ofstream&>(strm) << var;
return strm;
};
除了一件小事让我困惑之外,它工作得很好。如果我这样使用它:
int main(){
OutputAndConsole oac("testLog.dat");
double x = 5.0;
oac << std::endl;
static_cast<OutputAndConsole&>(oac << "foo \n" << x << "foo").operator<<(std::endl);
oac << "foo" << std::endl;
}
然后所有std::endl 在控制台上的输出中都将被忽略,而它们在文件中正确显示。我的猜测是,当我使用std::endl 时,会调用ostream::operator<<,它将打印到文件而不是控制台。带有static_cast<OutputAndConsole&> 的行是我尝试调用正确操作员的业余尝试,但控制台上仍然只出现\n 的换行符。
为什么 std::endl 调用了错误的运算符?
我怎样才能调用正确的?
PS:我知道我可以毫无问题地使用\n,但我仍然想知道这里发生了什么以及如何解决它。
【问题讨论】:
-
如果您使用
'\n'结束一行,您将不会遇到此问题。你真的需要std::endl做的额外的东西吗? -
@PeteBecker 你是绝对正确的,我不需要它,但我仍然想了解出了什么问题以及如何解决它。
-
停止。
ostream已经有运营商来处理这些问题。让它完成它的工作并处理格式化的输出。您只需要将原始输出复制到另外两个流上。这是streambuf班级的工作。只需正确实现它并将所有操作重定向到其他两个缓冲区:Dr.Dobb's article,another link -
对于您的 PPS,您的过载优先级存在问题。
-
@tobi303:在链接的问题中,还有一个类似于给定链接的其他答案