char* aus funktionsrueckgabewert



  • Habe nun mal folgendes versucht:

    const std::string ShaderManager::loadCompiledShader(const std::string& name)
    {
    	ifstream in(name.c_str(), ios::in || ios::binary);
    
    	in.seekg(0, ios::end);
    	std::streamoff length = in.tellg();
    	in.seekg(0, ios::beg);
    
    	vector<char> buffer(length);	
    	in.read(&buffer[0], length);
    	in.close();
    
    	string strBuffer(buffer.cbegin(), buffer.cend());
    
    	return strBuffer;
    }
    

    Problem: Bereits das eingelesene ist "gecutted" (= nur 21 zeichen).
    Hat es jemand mal mit der geposteten datei versucht?



  • ios::in || ios::binary - da ist ein | zuviel.
    Flags verknüpft man mit | , nicht mit || .



  • @hustbaer:

    Danke, sehr guter Punkt.
    Geht nun! 🙂

    Vielen Dank nochmal an @hustbaer und 314159265358979!

    Hoffe es ist nicht <zu> tragisch, dass wir etwas vom Thema abgeschweift sind.
    Aber man sieht immer wieder, was fuer ein "riesen Rattenschwanz" hinter vermeintlich "einfachen" fragen liegt. 😃 Euch noch einen schoenen Abend!



  • Wie wärs mit dem:

    const std::string ShaderManager::loadCompiledShader(const std::string& name)
    {
      std::ifstream in(name.c_str(), ios::in | ios::binary);
      return std::string((std::istreambuf_iterator<char>(in)),
                         std::istreambuf_iterator<char>());
    }
    


  • 👍



  • 👍

    rattenschwanz schrieb:

    Wie wärs mit dem:

    const std::string ShaderManager::loadCompiledShader(const…
    

    Ich habe nur eine Sache anzumeckern: Das const beim Rückgabetyp sollte weg.

    (Wenn Du mir jetzt mit "Aber Scott Meyers schreibt, dass..." kommst, dann kann ich Dich beruhigen. Der würde das heute, zu Zeiten von C++2011 auch nicht mehr vorschlagen. Das gibt es sogar quasi Schwarz auf Weiß irgendwo in einer der englischen C++ Usenet Gruppen. Ich bin nur zu faul, es rauszusuchen…) 🙂

    Warum macht das const dort heute noch weniger Sinn als früher? Weil es "move semantics" verhindert und zu unnötigen Kopien führen kann.



  • krümelkacker schrieb:

    Ich habe nur eine Sache anzumeckern: Das const beim Rückgabetyp sollte weg.

    Die Funktionssignatur hab ich so von com_ptr<T> übernommen, ich selber würde das nie in eine Memberfunktion stecken.

    Aber kannst du mir erklären, wieso das const move semantics verhindert?

    Ich habs mit dem GCC getestet und das Objekt wird genau einmal erzeugt (also genau ein Destruktoraufruf). Schreibe ich return std::move(std::string(...)) hin, gibt es zwei Destruktoraufrufe (einmal Movekonstruktor), aber unabhängig vom const.



  • Der Move-Konstruktor sieht ganz einfach so aus:

    string::string(string&&);
    

    Und weil das keine Referenz-auf-const ist als Parameter, kann der move-ctor auch nicht verwendet werden, wenn Du ein "const string" als Quelle hast.

    Dass da u.U. "nur einmal" etwas erzeugt wird, kann daran liegen, dass der GCC "copy elisions" durchführt, sofern möglich -- also die Notwendigkeit eines Kopierens bzw Movens minimiert.


  • Mod

    Der Unterschied wird offenbar, wenn zugewiesen wird.
    (Man könnte auf die Idee kommen, einen Zuweisungsoperator der Form foo& operator(foo) zu verwenden, dann ist move immer möglich... seit der Einführung von noexcept ist das allerdings eine sehr schlechte Idee, da move dann möglicherweise Exceptions wirft, und die Standardbibliothek darauf allergisch reagieren könnte...

    Und auch ohne noexcept sollte eine Klasse mit so einem Zuweisungsoperator besser nicht als Member einer anderen Klasse eingesetzt werden, die kann dann nämlich ebenfalls nicht ordentlich gemoved werden.



  • Und es ist immer noch sinnlos, Binärdaten in einen String zu schreiben. Warum bleibst du nicht einfach bei std::vector<char>?
    (Und die "schöne" Iteratorversion kann u.U. wesentlich langsamer sein.)


Anmelden zum Antworten