Typ eines Klassen-Attributes als template typ



  • Hallo zusammen,

    Folgender Code funktioniert:

    template <class SendMessageType>
    class Sender
    {
    public:
    	void Send(SendMessageType& data)
    	{
    		// ...
    	}
    };
    
    template <class MessageType, class InternalType>
    class Distributor
    {
    public:
    	Distributor()
    	{
    		sender = new Sender<InternalType>();
    	}
    
    	void Distribute(MessageType& msg)
    	{
    		sender->Send(msg.data);
    	}
    
    	Sender<InternalType>* sender;
    };
    
    template <class InternalType>
    class Message
    {
    public:
    	string someMetaInformation;
    	InternalType data;
    };
    
    class TypeA {};
    
    class MessageA : public Message<TypeA>
    {
    };
    
    class TypeB {};
    
    class MessageB : public Message<TypeB>
    {
    };
    
    int main()
    {
    	Distributor<MessageA, TypeA> dist;
    	MessageA myData;
    	dist.Distribute(myData);
    
    	return 0;
    }
    

    Mich stört daran aber, dass ein Benutzer der Klassen (das Beispiel ist Teil eines Frameworks, das ich entwickle) für den Distributor immer 2 template typen angeben muss.

    1. Den Typ der Message (z.B. MessageA oder MessageB)
    2. Den internen Typen der Message, also den Typen des Members Message::data

    Daher lautet die Frage: Kann ich die template deklaration der Klasse Distributor so gestalten, das ich nur den Typen der Message (z.B. MessageA oder MessageB) übergebe und der Compiler daraus den internen Typen des Members Message::data automatisch herausfindet?

    Etwa in dieser Art (Pseudocode):

    template <class MessageType, class InternalType &MessageType::data>
    class Distributor
    {
     //...
    };
    

    Grüße,
    DarthZiu


  • Mod

    Etwa so?

    template <class MessageType> 
    class Distributor 
    {
        using InternalType = decltype(MessageType::data);
    };
    

    Und wenn das nicht kompiliert (da dein Compiler decltype nicht unterstützt), deklariere doch ein Typedef internal_type in Message .



  • Ja, wär schön. Hab aber leider vergessen, dass ich nicht mit C++11 arbeite.



  • Arcoth schrieb:

    Und wenn das nicht kompiliert (da dein Compiler decltype nicht unterstützt), deklariere doch ein Typedef internal_type in Message .

    Könntest du bitte ein kurzes Syntax-Beispiel posten? Ich weiß gerade nicht so recht, wie ich den typedef dann benutzen soll.

    DarthZiu



  • Oder füge einfach zu deiner Message-Klasse noch einen 'typedef' hinzu:

    typedef InternalType type;
    

    und benutze diesen dann in deinem Klassen-Template

    template <class MessageType>
    class Distributor
    {
    public:
        Distributor()
        {
            sender = new Sender<typename MessageType::type>();
        }
    }
    

    Oder auch hier wieder ein 'typedef':

    typedef InternalType typename MessageType::type;
    

    Dies funktioniert auch noch für C++98 (bzw. C++03).

    Aber eleganter ist wohl der neuere Ansatz mittels 'using'.

    Edit: oh, wie gut, daß ich meinen Beitrag doch nicht verworfen habe, nachdem Arcoth gepostet hatte 😉


  • Mod

    typedef InternalType typename MessageType::type;
    

    Bitte korrigieren.



  • Na gut:

    typedef typename MessageType::type InternalType;
    

    Wollte doch nur DarthZiu (und dich 😉 testen...



  • You made my day!

    Grandios, vielen Dank euch beiden. Habe gestern einen halben Tag vor Google verbracht, aber diese Lösung habe ich nicht gefunden.

    Grüße,
    DarthZiu


Anmelden zum Antworten