Unverständlicher Templatefehler



  • Hallo.
    Beim kompilieren meines Projektes treten immer wieder Templatefehler auf, deren Ursache nicht ausfindig machen kann.

    1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\sstream(724): error C2248: 'std::basic_ios<_Elem,_Traits>::basic_ios' : cannot access private member declared in class 'std::basic_ios<_Elem,_Traits>'
    1> with
    1> [
    1> _Elem=char,
    1> _Traits=std::char_traits<char>
    1> ]
    1> c:\program files (x86)\microsoft visual studio 10.0\vc\include\ios(176) : see declaration of 'std::basic_ios<_Elem,_Traits>::basic_ios'
    1> with
    1> [
    1> _Elem=char,
    1> _Traits=std::char_traits<char>
    1> ]
    1> This diagnostic occurred in the compiler generated function 'std::basic_stringstream<_Elem,_Traits,_Alloc>::basic_stringstream(const std::basic_stringstream<_Elem,_Traits,_Alloc> &)'
    1> with
    1> [
    1> _Elem=char,
    1> _Traits=std::char_traits<char>,
    1> _Alloc=std::allocator<char>
    1> ]

    Ich weiß dass der Fehler in dem Copy-Constructor von stringstream auftritt ... allerdings werden in dem Projekt an keiner Stelle stringstreams kopiert!

    In meinem Projekt werden außer in dieser Klasse KEINE Streams der STL genutzt:

    class WinException : public std::exception
    {
    public:
    
    	/**
    	*Constructor
    	*Prepares error information
    	*@param causedIn Where did the error happen?
    	*@param failedName Which WinAPI-function failed?
    	*@param errorCode What does GetLastError say?
    	*/
    	WinException(	const std::string& causedIn,
    						const std::string& failedName,
    						DWORD errorCode) :	causedIn_(causedIn),
    													failedName_(failedName),
    													errorCode_(errorCode)
    	{
    		//Create a describing error string
    		char* errString;
    		DWORD ec = FormatMessageA(	FORMAT_MESSAGE_ALLOCATE_BUFFER |
    											FORMAT_MESSAGE_FROM_SYSTEM,
    											NULL,
    											errorCode,
    											0,
    											errString,
    											0,
    											NULL);
    
    		//Format a meaningfull error message
    		formattedError_ << causedIn_ << " Error : " << failedName_ <<
    		" failed with errorcode " << errorCode_ << "(" << 
    		(ec ? errString : "Unknown Error") << ")";
    
    		LocalFree(errString);
    	}
    
    	/**
    	*@return A formatted error message
    	*/
    	const char* what() const
    	{
    		return formattedError_.str().c_str();
    	}
    
    	/**
    	*@return Where did the error happen?
    	*/
    	const std::string& causedIn() const
    	{
    		return causedIn_;
    	}
    
    	/**
    	*@return Which WinAPI-function failed?
    	*/
    	const std::string& failedName() const
    	{
    		return failedName_;
    	}
    
    	/**
    	*@return What does GetLastError say?
    	*/
    	DWORD errorCode() const
    	{
    		return errorCode_;
    	}
    
    protected:
    
    	std::stringstream formattedError_;
    	std::string causedIn_;
    	std::string failedName_;
    	DWORD errorCode_;
    };
    

    Bin gerade echt ratlos.
    Mfg,
    Flo 😉



  • Ausnahme-Objekte müssen kopierbar sein. Daher kannst Du da keinen stream reinpacken.



  • krümelkacker schrieb:

    Ausnahme-Objekte müssen kopierbar sein. Daher kannst Du da keinen stream reinpacken.

    Da der Compiler einen 'std::basic_stringstream<_Elem,_Traits,_Alloc>::basic_stringstream(const std::basic_stringstream<_Elem,_Traits,_Alloc> &)' erzeugt, scheint ein stringstream im Gegensatz zu fstream etc kopierbar zu sein, oder irre ich mich da?



  • Nein, du irrst -) Nur weil ein Objekt einer Klasse erzeugt werden kann, so muß es noch lange nicht kopierbar sein.

    Speichere einfach den FormatString als std::string in deiner Klasse, d.h. benutze nur lokal std::stringstream und weise dann mittels .str() den Inhalt der std::string Membervariablen zu.



  • Icematix schrieb:

    Da der Compiler einen 'std::basic_stringstream<_Elem,_Traits,_Alloc>::basic_stringstream(const std::basic_stringstream<_Elem,_Traits,_Alloc> &)' erzeugt, scheint ein stringstream im Gegensatz zu fstream etc kopierbar zu sein, oder irre ich mich da?

    Der erwähnte Kopierkonstruktor ist privat (und höchstwahrscheinlich nicht definiert) und daher nicht zugreifbar.



  • krümelkacker schrieb:

    Ausnahme-Objekte müssen kopierbar sein. Daher kannst Du da keinen stream reinpacken.

    Mit einem stringstream sollte es aber klappen, wenn man Kopierkonstruktor/op= definiert und dort den string mit std::stringstream::str() setzt.
    Aber prinzipiell ist die Variante mit einem lokalen stringstream im Konstruktor hier die bessere Variante.



  • Der erwähnte Kopierkonstruktor ist privat (und höchstwahrscheinlich nicht definiert) und daher nicht zugreifbar.

    Aber ist ein compilergenerierter Kopierkonstruktor nicht automatisch public?

    class Foo
    {
    private:
      Foo(const Foo&);
    }
    

    wäre ja explizit nicht kopierbar.

    Das Problem lag doch eher daran, dass der wohldefinierte und auch öffentliche Kopierkonstruktor versucht hat nichtkopierbare Membervariablen zu kopieren.

    Aber danke, jetzt passts 🙂


Anmelden zum Antworten