for_each



  • Hallo zusammen,

    ich habe folgendes Problem:

    void save(std::string str) {
      out << str << "\n"; //out ist global
    }
    
    for_each(result.begin(), result.end(), save);
    

    Der ofstream in save ist bis jetzt global, da ich es nicht schaffe, diesen als Parameter der Funktion save zu übergeben. Wie funktioniert das im neuen C++ Standard?

    Danke



  • for(const auto& str : result) save( str, out );
    


  • Alternativ mit einem Lambda.
    Oder in dem man den ostream-Operator überlädt und in den ostream_iterator rüberkopiert.



  • Oder im C++03 Standard kann man es so machen

    #include <iostream>
    #include <string>
    #include <vector>
    #include <algorithm>
    
    struct functor
    {
    	functor(std::ostream& os) : ostream(os) {}
    
    	void operator ()(std::string const& str)
    	{
    		ostream << str << '\n';
    	}
    
    	std::ostream& ostream;
    };
    
    int main()
    {
    	std::vector<std::string> result(5);
    	result[0] = "string1";
    	result[1] = "string2";
    	result[2] = "string3";
    	result[3] = "string4";
    	result[4] = "string5";
    
    	std::for_each(result.begin(), result.end(), functor(std::cout));
    }
    


  • Um noch mehr Möglichkeiten aufzuzeigen:

    void save(const std::string& str, std::ostream& out)
    {
        out << str << "\n";
    }
    
    std::ofstream file(...);
    std::for_each(result.begin(), result.end(), std::bind(&save, _1, std::ref(file)));
    

    Benötigt using namespace std::placeholders;



  • Flashput schrieb:

    struct functor

    Functors-Codebloat sollten wir mal vergraben, vor Scham niemals wieder verwenden oder darüber sprechen.

    lamm da! schrieb:

    Alternativ mit einem Lambda.

    #include <iostream>
    #include <algorithm>>
    #include <vector>
    
    using namespace std;
    
    void save(string s)
    {
      cout << s << "\n";
    }
    
    int main()
    {
        vector<string> result{"1","2","3"};
        for_each(result.begin(), result.end(), [](string s){ save(s); });
        return 0;
    }
    

    Macht aber wenig Sinn wenn sowieso ein neuer Compiler verfügbar ist. decimad hat schon die richtige Lösung gepostet.



  • µ schrieb:

    for_each(result.begin(), result.end(), [](string s){ save(s); });
    

    Macht aber wenig Sinn

    Da hast du Recht, du leitest den Aufruf unverändert weiter 😉

    Wenn, dann

    std::ofstream file(...)
    auto lambda = [&file] (const std::string& s) { save(s, file); };
    

    Aber nimm decimads Lösung, die ist am simpelsten.



  • Ok, danke für die vielen Antworten.


Anmelden zum Antworten