如何解决ofstream
int myfun(const int a) {
...
return rval;
}
执行多项操作。
我的意思是根据我可以传递的某些参数,对其进行修改,以编写有关其行为的调试信息或不进行调试。
在我要编写该信息的情况下,我也想传递ofstream
来使用。
而且我希望使用myfun
的应用程序仍然能够不做任何修改。
所以我理想上将更改为
int myfun(const int a,ofstream & ofs) {
...
if (!(ofs == NULL)) {
ofs << ...
}
...
if (!(ofs == NULL)) {
ofs << ...
}
return rval;
}
,其默认值类似于&ofs=NULL
。我知道NULL
不适合。
什么是合适的处理方式?
注释1 : 我可以在输出文件名中传递一个可选参数,但这不太灵活。
注释2 : 我也可以更改为
int myfun(const int a,const bool debug_info,ofstream & ofs) {
...
if (debug_info) {
ofs << ...
}
,其默认值为debug_info=false
。
我想这仍然需要ofs
的默认值,如上所述。
注释3 :
Default ofstream class argument in function中接受的答案提出了没有ofs
参数的重载。
就我而言,这可能行不通,因为我的意思是在“ ofs=NULL
”时不写任何内容。
注释4 :
This other answer显然有效,但对我来说似乎有些伪造,而且我不确定它是否提供与传递ofs
相同的功能。
相关:
Is there a null std::ostream implementation in C++ or libraries?
解决方法
我希望使用myfun的应用程序仍然可以正常运行,而无需进行任何修改。
如果是这样,请使用默认值为nullptr
的ofs
int myfun(const int a,ofstream *ofs = nullptr)
{
if (ofs != nullptr)
{
// (*ofs) << ... ;
}
// ...
}
您不能将引用参数ofstream& ofs
用于此类功能,因为引用不能为空。
制作一个抽象的Logger类。它具有一种记录消息的方法。在派生类中,您可以将日志记录添加到文件(流)中,或者什么都不做。您可以使用任何记录器,myfun()的实现保持不变。
#include <fstream>
class Logger {
public:
virtual void log(const char*) = 0;
};
class NullLogger: public Logger {
public:
void log(const char*) override {};
};
class FileLogger: public Logger {
public:
FileLogger(std::ofstream& s): ofs(s){}
void log(const char* msg) override {
ofs << msg;
}
private:
std::ofstream& ofs;
};
static NullLogger defaultLogger;
int myfun(const int a,Logger& logger=defaultLogger)
{
logger.log("hello");
// ...
logger.log("asdf");
}
int main(){
std::ofstream ofs;
FileLogger fileLogger(ofs);
NullLogger nullLogger;
myfun(10,fileLogger); // logs to file
myfun(10,nullLogger); // logs nothing
myfun(10); // also logs nothing
return 0;
}
,
在C ++ 17中,有一个涉及std::optional
的解决方案,但是由于它需要默认的可构造类型,因此也必须使用std::reference_wrapper
。
#include <fstream>
#include <optional>
#include <functional>
int myfun(const int a,std::optional<std::reference_wrapper<std::ofstream>> ofs)
{
if (ofs) {
ofs->get() << "...";
return 1;
}
else{
return 0;
}
}
#include <iostream>
int main(){
std::ofstream file;
//Calling is quite nice.
std::cout<<myfun(10,{file})<<'\n'; //Prints 1
std::cout<<myfun(10,{})<<'\n'; //Prints 0
}
该解决方案的缺点虽然很惯用,但在某些情况下却过于冗长且语法繁重。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。