尝试同时写入 std:out 和文件
trying to write std:out and file at the same time
我试图通过重载流在 c++ 中同时写入文件和标准输出
测试.h
#pragma once
#include <iostream>
using std::ofstream;
class OutputAndConsole:public ofstream
{
public:
std::string fileName;
OutputAndConsole(const std::string& fileName):ofstream(fileName),fileName(fileName){
};
template <typename T>
OutputAndConsole& operator<<(T var);
};
template <typename T>
OutputAndConsole& OutputAndConsole::operator<<(T var)
{
std::cout << var;
ofstream::operator << (var);
return (*this);
};
测试.cpp
OutputAndConsole file("output.txt");
file << "test" ;
文件中的输出是
01400930
但在控制台中是
test
我调试了它看起来像是进入的代码
_Myt& __CLR_OR_THIS_CALL operator<<(const void *_Val)
我做错了什么?
我不打算评论为什么你的方法不起作用,主要是因为它无法修补以正常工作。主要问题是你不能使用你的流,把它传递给一个预期std::ostream&
的东西,并且仍然写入两个流。但是,有一种相对简单但不一定明显的方法来实现您真正想要的东西:您将派生一个新的流缓冲区,即从std::streambuf
派生的类,并覆盖其overflow()
和sync()
函数。下面是一个简单演示的完整代码:
#include <streambuf>
struct teebuf
: std::streambuf
{
std::streambuf* sb1_;
std::streambuf* sb2_;
teebuf(std::streambuf* sb1, std::streambuf* sb2)
: sb1_(sb1), sb2_(sb2) {
}
int overflow(int c) {
typedef std::streambuf::traits_type traits;
bool rc(true);
if (!traits::eq_int_type(traits::eof(), c)) {
traits::eq_int_type(this->sb1_->sputc(c), traits::eof())
&& (rc = false);
traits::eq_int_type(this->sb2_->sputc(c), traits::eof())
&& (rc = false);
}
return rc? traits::not_eof(c): traits::eof();
}
int sync() {
bool rc(true);
this->sb1_->pubsync() != -1 || (rc = false);
this->sb2_->pubsync() != -1 || (rc = false);
return rc? 0: -1;
}
};
#include <fstream>
#include <iostream>
int main()
{
std::ofstream fout("tee.txt");
teebuf sbuf(fout.rdbuf(), std::cout.rdbuf());
std::ostream out(&sbuf);
out << "hello, world!n";
}
显然,tee-stream的创建可以很好地打包,但这看起来如何并不重要。重要的是,可以为IOStreams创建自定义目标(或源),并且它不涉及任何尝试从std::ostream
继承。从std::ostream
(或std::istream
)继承的唯一原因是使使用自定义流缓冲区初始化流更容易。
问题
ofstream::operator << (var);
这是您使用ofstream::operator<<
作为限定函数调用。您要求函数查找查找 ofstream
的成员函数;成员的最佳匹配是void*
,而打印实际字符串内容的char*
专用化是一个自由函数(即不是成员函数)。
如果您使用cout
执行此操作,您也会发现同样的问题:
std::cout.operator<<(var);
解决方案
这可能会做到:
static_cast<ofstream&>(*this) << var;
因为您仍在使用正常的运算符语法(具有这所需的所有重载分辨率),但使用ofstream
作为 LHS 操作数。
不过,我还没有真正测试过它。
结论
顺便说一句,您的operator<<
也应该是一个自由功能,以便适应此约定。
所以:
struct OutputAndConsole : std::ofstream
{
OutputAndConsole(const std::string& fileName)
: std::ofstream(fileName)
, 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;
};
我还冒昧地做了一些小的语法调整。
相关文章:
- .cpp和.h文件中的模板专用化声明
- -bash:/a.out:无法执行二进制文件:Exec格式错误
- 为什么 .out 文件是十六进制而不是二进制
- g++ 不创建"a.out"文件
- 如何将文件写入当前目录而不是Bazel-Out
- 为什么PHP的Shell_exec没有给出某些A.Out文件的输出
- g++.exe:error:libgomp-1.dll:没有这样的文件或目录;make:***[Out release]
- Android Cmake编译器正在生成带有额外前缀和符号后缀的.out文件
- 尝试同时写入 std:out 和文件
- 如何通过键入 "a.out < textfilename.txt" 让 .out 文件通过终端读取文本文件
- 什么可能导致错误:"Fatal Error: Out of memory - aborting"简单地包含头文件?
- a.out Linux 可执行文件是哪个程序
- 如何将llvm::out()重定向到文件
- 在 C++ 文件上的 Windows 环境中运行 Unix 类似命令"./a.out <data.txt"
- 可以在windows中运行.out文件吗
- 编译器g++不能创建a.out文件
- 读/写同一个文件(获取gmon.out)
- 将打开的文件的ios_base从'out'更改为'app'而不关闭文件
- 如何在unix环境中使用.in和.out文件进行测试
- 为什么编译文件时文件名为"a.out" C++?