gpt4 book ai didi

c++ - 如何将 C 文件指针转换为通用 C++ 流?

转载 作者:行者123 更新时间:2023-12-03 23:00:43 30 4
gpt4 key购买 nike

考虑以下 C 代码:

void openFile(const char *mode, char *filename, FILE **fileptr)
{
...
*fileptr = fopen(filename, mode);
...
}

FILE *logstream;
if (LOG_FILE_ENABLED)
{
openFile("w", "mylogfile.txt", logstream);
}
else
{
logstream = stderr;
}

fprintf(logstream, "[DEBUG] Some debug message...\n");
fclose(logstream);
我试图将其翻译成惯用的 C++。我怎样才能过载 openFile()这样它需要一个 std::ofstream ,但保留 logstream流不可知?我假设它会是这样的:
void openFile(const char *mode, char *filename, std::ofstream &ofs)
{
...
ofs.open(filename);
...
}

std::ostream logstream;
if (LOG_FILE_ENABLED)
{
logstream = std::ofstream();
openFile("w", "mylogfile.txt", logstream);
}
else
{
logstream = std::cerr;
}

logstream << "[DEBUG] Some debug message..." << std::endl;
logstream.close();
然而,这显然是非常不正确的——你甚至不能初始化一个普通的 std::ostream像那样。我应该如何处理这个 - 最好同时避免使用原始指针?

最佳答案

我会将实际工作转移到一个单独的函数或 lambda 中,它需要一个 std::ostream作为输入。然后调用者可以决定哪种类型的 std::ostream传入,例如:

void doRealWork(std::ostream &log)
{
...
log << "[DEBUG] Some debug message..." << std::endl;
...
}

if (LOG_FILE_ENABLED)
{
std::ofstream log("mylogfile.txt");
doRealWork(log);
}
else
{
doRealWork(std::cerr);
}
或者:
auto theRealWork = [&](std::ostream &&log)
{
...
log << "[DEBUG] Some debug message..." << std::endl;
...
}

if (LOG_FILE_ENABLED) {
theRealWork(std::ofstream{"mylogfile.txt"});
} else {
theRealWork(static_cast<std::ostream&&>(std::cerr));
}
更新 : 否则,你可以做更多这样的事情:
using unique_ostream_ptr = std::unique_ptr<std::ostream, void(*)(std::ostream*)>;

unique_ostream_ptr logstream;
if (LOG_FILE_ENABLED) {
logstream = unique_ostream_ptr(new std::ofstream("mylogfile.txt"), [](std::ostream *strm){ delete strm; });
} else {
logstream = unique_ostream_ptr(&std::cerr, [](std::ostream *){});
}

*logstream << "[DEBUG] Some debug message...\n";
或者:
using shared_ostream_ptr = std::shared_ptr<std::ostream>;

shared_ostream_ptr logstream;
if (LOG_FILE_ENABLED) {
logstream = std::make_shared<std::ofstream>("mylogfile.txt");
} else {
logstream = shared_ostream_ptr(&std::cerr, [](std::ostream*){});
}

*logstream << "[DEBUG] Some debug message...\n";

关于c++ - 如何将 C 文件指针转换为通用 C++ 流?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65941918/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com