Template Spezialisierung



  • Hey,
    da ich meine template Klasse anfangs nur mit VC++ entwickelt habe und diese da problemlos kompilierbar war stehe ich jetzt mit einem Intel Compiler oder gcc (beide aktuell) vor Problemen.
    Diese fangen mit "explicit specialization in non-namespace scope" an gehen über Klammerfehler und hören bei sehr langen Fehlermeldungen auf.

    Der Source:

    Dieser besteht zuerst aus einer Tupel ähnlichen Konstruktion zum speichern beliebiger Anzahl an Variablen. Diese ist im ersten Source Block zu finden. Im zweiten Block befindet sich die entsprechende Zugriffsstruktur. Im vollständigen Programm stecken beide Strukturen innerhalb des privaten Bereiches einer äußeren Klasse.

    Fallen euch die Problemstellen auf? Hoffe das es sich nur um Kleinigkeiten handelt, da ja VC++2013 problemlos durchläuft.

    Grüße Dominik

    template<class... TArgs_>
    	struct _cell;
    
    	template<>
    	struct _cell<>
    	{
    	public:
    		inline const std::string write(char delim, _cell<> c){ return std::string(); }
    	};
    
    	template<class TFirst_, class... TArgs_>
    	struct _cell<TFirst_, TArgs_...> : _cell<TArgs_...>
    	{		
    	private:
    		template <class T>
    		struct deref_str;
    
    		template <class T>
    		struct deref_str<T*>
    		{
    			inline static const T& deref(T* x){ return *x; }
    		};		
    
    		template <class T>
    		struct deref_str
    		{
    			inline static const T& deref(T& x){ return x; }
    		};	
    
    	public:
    
    		TFirst_ data;
    
    		inline const std::string write(char delim, _cell<TFirst_, TArgs_...> c)
    		{
    			std::stringstream sstr;			
    			sstr << deref_str<TFirst_>::deref(c.data)  << delim << (_cell<TArgs_...>::write(delim, c));
    			return sstr.str();
    		}
    
    	};
    

    Zugriffs Struktur:

    template<int id_, class... TData_>
    	struct access_cell;
    
    	template<class TFirst_, class... TRest_>
    	struct access_cell<0, TFirst_, TRest_...>
    	{
    		typedef TFirst_ DataType;
    		typedef _cell<TFirst_, TRest_...> CellType;	
    	};
    
    	template <int id_, class TFirst_, class... TRest_>
    	struct access_cell<id_, TFirst_, TRest_...>	: public access_cell<id_ - 1, TRest_... >{};
    
    	template<int id>
    	using DataType = typename access_cell<id, TArgs...>::DataType; 
    	template<int id>
    	using CellType = typename access_cell<id, TArgs...>::CellType;
    

    Zugriffs Befehl :

    ((CellType<id>&)this->cell).data
    

  • Mod

    template <class T>
            struct deref_str;
    
            template <class T>
            struct deref_str<T*>
            {
                inline static const T& deref(T* x){ return *x; }
            };     
    
            template <class T>
            struct deref_str
            {
                inline static const T& deref(T& x){ return x; }
            };
    

    Das ist nicht erlaubt, wie die Fehlermeldung schon sagt (§14.5.5/5). Das muss außerhalb jeglicher Klassen definiert werden.

    da ja VC++2013 problemlos durchläuft.

    VC++ lässt so einiges durchgehen. Mach dir keine Hoffnungen.

    inline const std::string write(char delim, _cell<> c){ return std::string(); }
    

    Du kannst das _cell<> durch _cell ersetzen. Genau wie in der unteren part. Spezialisierungen das _cell<TFirst_, TArgs_...> .



  • So,
    ich hab die Klassen schrittweise umgebaut und es Kompiliert erst mal vollständig.
    Bis ich den Code

    template<int id>
    	inline DataType<id> get()
    	{
    		return ((CellType<id>)this->cell).data;
    	}
    

    einfüge.

    Dann wirft der Intel Compiler die Fehlermeldung:

    error : expected a ">"
    1> using DataType = typename access_cell<id, TArgs...>::DataType;
    1> ^
    1> detected during instantiation of type "minimalBeispiel<TArgs...>::DataType<id>" at line 169

    Die entsprechende Stelle im Source ist die Nachfolgende.
    TArgs ist ein Template der umgebenden Klasse. Die grundlegende Spezifikation hat sich zum obigen Beispiel nicht verändert.

    template<int id>
    	using DataType = typename access_cell<id, TArgs...>::DataType;
    	template<int id>
    	using CellType = typename access_cell<id, TArgs...>::CellType;
    

    Grüße Dominik


Log in to reply