2016-06-30 108 views
2

Ich möchte eine Funktion deklarieren, die standardmäßig auf std::out schreibt, aber optional auch das Schreiben in einen anderen Ausgabestrom ermöglicht, falls einer vorhanden ist. Zum Beispiel:std :: ostream als optionaler (!) Funktionsparameter

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; 
    } 
} 

Einstellung nullprt offensichtlich nicht funktioniert, aber wie kann dies geschehen?

+0

Related: http://StackOverflow.com/Questions/11826554/Standard-No-Op-Output-Stream – lorro

+2

Es sieht für mich viel natürlicher wäre, zwei Überladungen, eine mit zwei Argumente, und eine mit drei Argumenten. – Hurkyl

+1

@Hurkyl: oder halten Sie den einen mit 2 Argument und übergeben Sie einen "Tee_stream". – Jarod42

Antwort

1

Ich würde einfach Funktion Überlastung verwenden, anstatt Standardargumente

// 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; 
} 

Alle drei Versionen dieser Funktionen können Sie alles tun mögen. Abhängig von Ihren Bedürfnissen kann jeder mit den anderen implementiert werden.

Wenn Sie die Logik in den drei Funktionen verschachteln müssen (z. B. Anweisungen, die other beeinflussen, müssen Sie mit Anweisungen aus einer der anderen Funktionen verschachtelt sein), führen Sie Hilfsfunktionen ein, um die Logik in separaten, detaillierteren Teilen zu implementieren.

+0

Dies ist vielleicht die einfachste und direkte Lösung, die auch keinen Boost erfordert. – Stingery

7

mit Zeigern oder boost::optional

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

oder

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

Ich würde nur den 'boost :: optional'-Ansatz beibehalten ... Oder zumindest vor dem Zeiger-Ansatz. – Nawaz

+1

@Nawaz: Manche wollen nicht, dass die Abhängigkeit ansteigt :-(. Also bis 'optional' in' 'std ::' ... steht – Jarod42

+0

Optionale Referenzen, die von der Std ausgeschlossen wurden, habe ich überprüft. – Yakk

1

Sie können boost::optional oder Zeiger, wie suggested by @Jarod42 verwenden. Beide Ansätze erzwingen jedoch die Verwendung von bedingten Anweisungen im Funktionskörper.

ist hier ein anderer Ansatz, dessen Vorteil ist die Einfachheit der Funktion Körper:

void print_function(std::string & str, 
       std::ostream & out = std::cout, 
       std::ostream& other = null_stream) 
{ 
    out << str; 
    other << str; //no "if" required here. 
} 

Und hier ist, wie Sie null_stream Objekt definieren:

#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 Hier ist ein std::ostream die tut nichts. Es gibt other ways, um es auch zu implementieren.

Hoffe, dass hilft.