Std::ostream作为可选(!)函数参数

std::ostream as optional (!) function parameter

本文关键字:参数 函数 ostream Std      更新时间:2023-10-16

我想声明一个函数,默认情况下写入std::out,但也可以选择允许写入另一个输出流,如果提供的话。例如:

print_function(std::string & str, 
               std::ostream & out = std::cout, 
               std::ostream & other = nullptr) // <-- how to make it optional???
{
    out << str;
    if (other == something) // if optional 'other' argument is provided
    {
        other << str;
    }
}

设置nullprt显然不工作,但这是如何做到的?

与指针,或boost::optional

void print_function(std::string & str, 
               std::ostream & out = std::cout, 
               std::ostream* other = nullptr)
{
    out << str;
    if (other)
    {
        *other << str;
    }
}

void print_function(std::string & str, 
               std::ostream & out = std::cout, 
               boost::optional<std::ostream&> other = boost::none)
{
    out << str;
    if (other)
    {
        *other << str;
    }
}

我会简单地使用函数重载,而不是默认参数

// declare the functions in a header
void print_function(std::string &str);
void print_function(std::string &str, std::ostream &ostr);
void print_function(std::string &str, std::ostream &ostr, std::ostream &other);
// and in some compilation unit, define them
#include "the_header"
void print_function(std::string &str)
{
       print_function(str, std::cout);
}
void print_function(std::string &str, std::ostream &ostr)
{
     // whatever
}
void print_function(std::string & str, 
                    std::ostream &ostr, 
                    std::ostream &other)
{
    print_function(str, ostr);
    other << str;
}

这三个版本的函数都可以做任何你喜欢的事情。根据您的需要,任何一个都可以使用其他的来实现。

如果您需要在三个函数中交叉使用逻辑(例如,影响other的语句需要与来自其他函数之一的语句交叉使用),则引入辅助函数以单独的、更细粒度的部分实现逻辑。

您可以使用boost::optional或指针,如@Jarod42所建议的。然而,这两种方法都强制你在函数体中使用条件语句。

下面是另一种方法,其优点是函数体简单:
 void print_function(std::string & str, 
              std::ostream & out = std::cout, 
              std::ostream& other = null_stream)
{
     out << str;
     other << str;  //no "if" required here.
 }

你可以这样定义null_stream对象:

#include <boost/iostreams/stream.hpp>
#include <boost/iostreams/device/null.hpp>
boost::iostreams::stream<boost::iostreams::null_sink> null_stream {
          boost::iostreams::null_sink{} 
};

这里null_stream是一个不做任何事情的std::ostream 。还有其他方法可以实现它。

希望对你有帮助。